Skip to content

Size Mismatch

; a program to add three numbers accessed using a single label
[org 0x0100]
     mov  ax, [num1]         ; load first number in ax
     mov  bx, [num1+2]       ; load second number in bx
     add  ax, bx             ; accumulate sum in ax
     mov  bx, [num1+4]       ; load third number in bx
     add  ax, bx             ; accumulate sum in ax
     mov  [num1+6], ax       ; store sum at num1+6
     mov  ax, 0x4c00         ; terminate program
     int  0x21

num1: dw   5
      dw   10
      dw   15
      dw   0

if we change the dw to db, then that means when mov ax, [num1] is encountered, it stores 5 and 10 both into the ax register because the register is 16-bit.
Therefore, it reads 2 bytes (2 numbers) instead of 1.

Similarly, bx does the same, it stores the 3rd and 4th number.
rest of the code becomes useless because now [num1+4] is going to point beyond of what we have defined.

We can fix this by replacing the AX register by AL, BX with BL and the [num1+2] offsets to [num1+1] etc so the offset is of 1 byte this time, instead of 2.

; a program to add three numbers accessed using a single label
[org 0x0100]
     mov  al, [num1]         ; load first number in ax
     mov  bl, [num1+1]       ; load second number in bx
     add  al, bl             ; accumulate sum in ax
     mov  bl, [num1+2]       ; load third number in bx
     add  al, bl             ; accumulate sum in ax
     mov  [num1+3], al       ; store sum at num1+6
     mov  al, 0x4c00         ; terminate program
     int  0x21

num1: db   5
      db   10
      db   15
      db   0

If we try doing something like mov ax, bl, this would be illegal because bl is of 1 byte meanwhile ax is of 2 bytes.

If we do something like:

mov [num1], 5

Although it is a legal statement but the sizes are unknown this time.
That is why we need

mov byte [num1], 5
mov word [num1], 5

Register Indirect Addressing

Sometimes, we need to access data across 100 or more data elements.
In that case, manually writing the memory addresses isn’t really possible.

[org 0x100]

    mov bx, num1  ;point bx to first number
    mov ax, [bx]  ;load first number in ax
    add bx, 2     ;advance bx to second number (2 bytes)
    add ax, [bx]  ;add second number to ax
    add bx, 2     ;advance bx to third number (2 bytes)
    add ax, [bx]  ;add third number to ax
    add bx, 2     ;advance bx to result (2 bytes)
    mov [bx], ax  ;store sum at num1+6
    mov ax, 0x4c00
    int 0x21

num1: dw 5, 10, 15, 0

Remember, a label is just a memory address.
using [] means accessing the contents of that memory.

; a program to add ten numbers
[org 0x0100]
    mov bx,num1 ; point bx to first number
    mov cx,10 ; load count of numbers in cx
    mov ax,0 ; initialize sum to zero

    l1:add ax,[bx] ; add number to ax
    add bx,2 ; advance bx to next number
    sub cx,1 ; numbers to be added reduced
    jnz l1 ; if numbers remain add next

    mov [total],ax ; write back sum in memory

    mov ax,0x4c00 ; terminate program
    int 0x21

num1: dw 10,20,30,40,50,10,20,30,40,50
total: dw 0

The program is doing as follows: 1. store address num1 into bx. 2. store 10 into cx (for counting). 3. store 0 in ax 4. set a label which adds contents of bx to ax. 5. Move the pointer bx. 6. Decrement the counter by 1. 7. Jump to step 4 if cx(memory in preceding instruction) is not 0.

JNZ stands for “jump if not zero”

The memory in the preceding instruction should be zero for the zero flag to be set so the jump instruction can stop but this flag is only set when the result in destination is zero by a Mathematical or Logical operation.
Meaning, doing mov ax, 0 will not set the zero flag as it is not a math or logic operation

Since we are using a register to access memory.
Therefore, we call this sort of access as register-indirect-memory-access.

If we use BX or BP then it is called based-addressing.
If we use DI or SI then it is called indexed-addressing.