Search code examples
assemblyx86-16simplify

How can I write this code more efficient?


So one of the problems that were in the exam for me is to make this group of code more efficient with at least 1 line less command. And I didn't know how to do it.The goal of this code is to get the 4 right bits of the first number,the left bits from the second number from the array (which its address is located in si) and then to merge those 8 bits- and to put the result in a 8 bit register. 0dh is the ASCII of enter,I need to make sure that enter isn't one of the chars that user had input,if it does 0 should replace it.(The array is an array of characters) This is the code:

I thought maybe she just meant to get the line that doesn't effect the returned value to outside of the function but she told me that that's not what she meant so its wrong.

cmp [byte ptr si],0Dh
je LessThan4
mov al,[si]
shl al,4;(a)-first nibble
inc si
cmp [byte ptr si],0Dh
je LessThan4
mov dl,[si]
and dl,240;11110000b
shr dl,4;(b)-second nibble 
or al,dl;al=ab merging the nibbles
inc si
jmp Normal
LessThan4:
mov[byte ptr si],0
Normal:
ret

The excepted result is using 1 command,that will swap 2 commands in the current code. Edit: Honestly I don't know why did I use this line: mov[byte ptr si],0 I don't need it,I need to put 0 instead of enter if there is enter. But this is happening alone because the function ends if there is an enter in the array,and 0 is what replacing the second nibble or both of the nibbles but I did need to make sure al is 0. If this is what she meant im so embarrassed and tilted because I might not be able to get to the subject I want to learn next year in our class.): ): ): ): ): I should have been able to see it pretty easily so that's really bad for me...


Solution

  • The expected result is using 1 command, that will swap 2 commands in the current code.

    The and dl, 11110000b instruction before the shr dl, 4 instruction is redundant. The shift right will by itself throw out the low 4 bits.

    There are a couple of things that I would like to draw your attention to.

    • How the nibbles are combined

      get the 4 right bits of the first number, the 4 left bits of the second number and then merge those 8 bits

      The logical way to present this combination of bits would be to keep those 4 right bits aka low nibble in the low nibble of the result, and to keep those 4 left bits aka high nibble in the high nibble of the result. Your code doesn't do it that way and neither do the other answers. Perhaps because they want to mimic what you've written.

      If the 1st number is in AL and the 2nd number is in AH then and ax, 0F00Fh will mask away the unwanted bits and or al, ah will leave the combination in AL

    • How 13 is replaced by 0

      0Dh is the ASCII of enter. I need to make sure that enter isn't one of the chars that user had input. If it does 0 should replace it.

      I think that you could be misinterpreting this "...0 should replace it."
      Probably this is DOS and input was terminated with enter, and so a carriage return (13) was appended to the inputted characters. What your teachers warns about is that the value 13 cannot become part of the result. You replace it with zero in the calculation but not in memory.

    If this is a one-time calculation

    Returning a result in AL and keeping SI put.

        mov     ax, [si]
        cmp     al, 13
        jne     L1
        xor     ax, ax      ; Falling through shaves off an instruction
    L1:
        cmp     ah, 13
        jne     L2
        xor     ah, ah
    L2:
        and     ax, 0F00Fh
        or      al, ah
        ret
    

    If this has to be repeated for all characters in the string

    Always returning a result in AL and having SI point at either the remaining characters or the terminating carriage return.

    Again:
        mov     ax, [si]
        cmp     al, 13      ; If 1st byte is 13, then next byte is just garbage!
        je      CR1         ; ... so no further interpretation needed
        and     al, 0Fh
        inc     si
        cmp     ah, 13      ; If 2nd byte is 13, then result is based on 1st byte
        je      CR2         ; ... and that kind-of zero-replacement
        and     ah, 0F0h
        inc     si
        or      al, ah
    
        ...
    
        jmp     Again
    
    CR1:
        xor     al, al
    CR2:
        ...