Search code examples
assemblyx86-16emu8086

Why am I getting zero from mov ax, bx+si+1?


    mov     ax,10
    mov     bx,4
    mov     si,ax
    mov     ax,bx+si+1
    LEA     ax,[bx+si+1]

When I add bx,si and 1 together and move to ax , the result is 0. At the next line, when I use LEA it works and I get 15.

Why am I getting zero when using move?


Solution

  • Your question is : "Why am I getting zero from mov ax, bx+si+1?". It's hard to give you an accurate answer because you forgot to tell what compiler you are using and your code snippet doesn't include the data segment so we can't see your data. What we can do is to test your code with some numbers in the data segment and see the results :

    .model small
    .stack 100h
    .data    
    xy db 0A0h,0A1h,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,0AAh,0ABh,0ACh,0ADh,0AEh,0AFh,0B0h
    .code
      mov  ax, @data
      mov  ds, ax
    
      mov  ax, 10
      mov  bx, 4
      mov  si, ax
      mov  ax, bx+si+1       ;◄■■ #1 (EXPLANATION BELOW ▼)
      LEA  ax, [bx+si+1]     ;◄■■ #2 (EXPLANATION BELOW ▼)
    

    Let's illustrate what happens here:

    enter image description here

    This is what is going on:

    #1 Because of the presence of a base register (bx) and an index register (si) the sum is interpreted as a memory addressing, so the code gets the data in memory location 15. ax register size is 2 bytes, so the result is that ax gets 2 bytes starting at memory location 15, in our data segment those 2 bytes are 0AFh and 0B0h. al is the lower byte of ax, so the first byte (0AFh) stores there, the higher byte ah gets the second byte (0B0h), and this is how ax becomes 0B0AFh.

    #2 We said that the presence of the base register bx and the index register si is interpreted as a memory addressing, so [bx+si+1] points to memory location 15 (0AFh). Instruction lea stands for load effective address, its purpose is to get an address from inside the data segment. Your line of code is getting the effective address of memory location 15 (0AFh), which is 15.

    So much theory requires a demonstration, and here it is:

    Next is a screenshot from EMU8086 : the BLUE arrow points to the original line of code, the GREEN arrow points to the line of code as it is been interpreted (as a memory addressing), and the RED arrow shows the effect in register ax (B0AFh).

    enter image description here

    Now the screenshot for the next instruction : the BLUE arrow points to the original line of code, the GREEN arrow points to the line of code as it is been interpreted (notice it's identical to the previous one), and the RED arrow shows the effect in register ax (0Fh).

    enter image description here

    Finally, let's test the code in Visual Studio 2013 : next screenshot proves that mov ax, bx+si+1 is invalid, and the other line gives the same result as EMU8086 (ax=0FH) :

    enter image description here

    So, "why are you getting zero from mov ax, bx+si+1?" Because you probably have a zero in memory location 15 inside your data segment. You maybe thought that bx+si+1 was going to give you a normal number, 15, but now you know that using base and index registers will be interpreted as memory addressing, so you don't get the number 15 but the data inside memory location 15.