Search code examples
assemblyx86bit-shift

How do I shift left in assembly with ADD, not using SHL?


Our teacher in class gave us an assignment to do. The issue is that we did not cover bit shifting in class, so I am a little bit lost on how to do this. In the assignment instructions he tells us the following:

  • We can only use mov, add , sub instructions to complete the assignment.
  • He gives us the following hint: Think about how add instructions could be used to achieve shifting. For example, suppose we have the following 8-bit binary number: 00000011, After shifting this binary number to the left we have. 00001100.

We start out with 4 variables:

  • var1 BYTE 41h
  • var2 BYTE 42h
  • var3 BYTE 43h
  • var4 BYTE 44h

The first part of the assignment is to move these around so we end up with the following order:

  • var1 = 44h
  • var2 = 41h
  • var3 = 42h
  • var4 = 43h

I successfully completed this part, I just provided this for context. The next part is where I am having issues. In part two we need to move these vars into register eax. var1 must be stored in the highest byte of eax, var2 in the second highest, war3 in the second lowest byte and var4 in the lowest.

The end result should give eax = 444144243

So here is what I do know about this problem:

  • I know that I cannot directly refer to the highest 16 bits of eax.
  • I can refer to ax and al.
  • I know I need to use the binary values of these hex values to shift them to the left by adding 1 or something like that.

How do I go about shifting var1 so that it ends up in the upper 16 bits of eax and so forth with the other vars?

NOTE: I have no code as I have no idea where to even start with this part of the assignment. I do not want it solved, I just want help on finding the right path to take to solve it.


Solution

  • To shift a value to the left you need to ADD the same value to itself

    For example, if you have 0011

    0011 + 0011 = 0110 (shift 1 left)
    0110 + 0110 = 1100 (shift 1 left again)
    

    To solve your problem I would to the following (quick way)

    MOV ah, var1  (move 44h to 0000h -> 4400h)
    MOV al, var2  (move 41h to 4400h -> 4441h)
    ADD eax, eax    (4441h + 4441h = 8882h)
    ADD eax, eax    (8882h + 8882h = 11104h)
    ADD eax, eax    (11104h + 11104h = 22208h)
    ADD eax, eax    (22208h + 22208h = 44410h)
    ADD eax, eax    
    ADD eax, eax    
    ADD eax, eax   
    ADD eax, eax    (444100h)
    ADD eax, eax  
    ADD eax, eax  
    ADD eax, eax 
    ADD eax, eax    (4441000h)
    ADD eax, eax   
    ADD eax, eax   
    ADD eax, eax   
    ADD eax, eax    (44410000h)
    

    Now to the other part

    MOV ah, var3  (move 42h to 44410000h -> 44414200h)
    MOV al, var4  (move 43h to 44414200h -> 44414243h)
    

    Now your eax register is the following: 4441 4243h