out_a_nibble procedure

The procedure out_a_nibble appears simple but it involves quite a lot of thinking. Let's see how it should work to fit within the code of stack_to_string. The word, where to extract the nibbles from, is already in BX. CX changes from 4 to 1 and could be used as a selector of the nibble. The procedure coming after it expects the input to be in the low nibble of AL (bit 0 to bit 3) and will return the corresponding ASCII code in AL (bit7 to bit0). As a consequence, the procedure out_a_nibble must deliver output in the form AL = 0000???? in binary. Now suppose that BX = 0xABCD so the most significant nibble is 0xA and the less significant nibble is 0xD. The question is: which selection order shall I use? stack_to_string stores the bytes from left to right when writing the string and the register DI increases automatically every time. So it's better to select the nibbles in BX also from left to right. As CX changes from 4 to 1, the logical consequence is that the selected nibble in AL changes from 0xA to 0xD. Since we want our output to be available in AL then the best way to proceed is to copy the value of BX into AX and then perform a right shift that places the desired nibble in the position from bit 3 to bit 0 of AL. Another constrain is that a right shift of any bit different from 1 can only be performed specifying the amount in CL1, but CX already holds the value of the counter. Having considered all of these constrains I came up with the following code which, I think, is ok. Of course and as usual, you are encouraged to think differently and to try your own way.

out_a_nibble - final
out_a_nibble: ################################################################################ # # This procedure returns in AL (bit0 to bit3) the value of the selected nibble # in BX. The selection is done depending on the value in CX # # INPUT: BX = word to select the nibble from # CX = nibble selection inside the word in BX # OUTPUT: AL = selected nibble # REGISTER USAGE: DX # THIS ONE CALLS: --- # # EXAMPLE: BX: CX: AX: # ABCD 0001 000D # ABCD 0002 000C # ABCD 0003 000B # ABCD 0004 000A # ################################################################################ mov ax, bx # it copies the value in AX. mov dx, cx # store the value of CX to resume it before exit. # SHR instruction must use CL register: # before shift | after shift # -------------+-------------- # ABC[D] | ABC[D] --> 0 bits shift # AB[C]D | 0AB[C] --> 4 bits shift # A[B]CD | 00A[B] --> 8 bits shift # [A]BCD | 000[A] --> 12 bits shift # # Relationship table for the value of shift: # index | value of shift # x | y = f(x) # ------+---------- # 4 | 12 # 3 | 8 # 2 | 4 # 1 | 0 # # Relationship formula for the value of shift: # y = 4*(x-1) --> CL = 4*(CX - 1) desired target dec cx # CX = CX - 1 --> CL = (CX - 1) step 1 shl cx, 1 # CX = 2*CX --> CL = 2*(CX - 1) step 2 shl cx, 1 # CX = 2*CX --> CL = 2*2*(CX - 1) final step shr ax, cl # select the nibble and ax, 0x000f # mask remaining bits mov cx, dx # restore CX before return ##################### # end of procedure ##################### ret


  1. On page 2-39 of the 8086 INTEL Manual, you can read that one can specify the count for the shift and rotate instruction either as the constant 1 or as the register CL. [click back]

<PREV.  -  ALL  -  NEXT>

Comments