low register and high register swapped places?

IDEAL
MODEL small
STACK 100h
jumps
p186
DATASEG

array dw 312, 340, 311, 300

CODESEG
proc example
    pusha
    mov al ,4 ;number of elements in array
    mov bl, 0 ;index
    label1:
    mov cx, [array + bx] ;here, every second element ch and cl are swapped
    inc bl
    cmp bl, al
    jb label1
    popa
    ret
endp example

start:
    mov ax, @data
    mov ds, ax
    
    call example
exit:
    mov ax, 4c00h
    int 21h
END start

My assembly code. cx is okay in 1st and 3rd iterations but in the 2nd and 4th ones for some reason cl and ch swapped their values with each other. Im really overwhelmed with this and I would appreciate some help, thanks!

>Solution :

The elements of array are words, 2 bytes each, but you only increment your index bx by 1 on each iteration of your loop. Addresses on x86 are in units of bytes, so on the next loop iteration, you load from the middle of the word, and you end up with one byte from one element and another byte from the other.

Probably simplest to do everything in terms of bytes, instead of elements. (In 32- or 64-bit code you could use the scale addressing mode, mov cx, [array+ebx*2], and then keep counting ebx in elements, but that’s not available in 16-bit real mode.)

Also, the high half of bx is uninitialized. It’s probably best to just use 16-bit values for your indices.

I’d rewrite as (untested):

CODESEG
proc example
    pusha
    mov ax, 4*2 ;number of bytes in array
    mov bx, 0 ;index
label1:
    mov cx, [array + bx]
    ; presumably do something with cx here
    add bx, 2
    cmp bx, ax
    jb label1
    popa
    ret
endp example

Leave a Reply