Reputation: 11
I have written an assembly program that sorts an array using bubble sort. I am getting errors.
This is the full code:
org 100h
section .data
array db 5, 3, 7, 1, 4, 9, 2, 8, 6
array_size db 9
new_line db 0xA
comma db ','
section .bss
temp resb 1
output resb 2
section .text
start:
mov al, [array_size]
dec al
mov cl, al
bubble_sort:
xor bx, bx
outer_loop:
cmp bx, cl
jge done
xor si, si
inner_loop:
mov al, [array_size]
sub al, bl
cmp si, al
jge next_outer_loop
mov al, [array + si]
mov dl, [array + si + 1]
cmp al, dl
jle next_esi
mov [temp], al
mov [array + si], dl
mov al, [temp]
mov [array + si + 1], al
next_esi:
inc si
jmp inner_loop
next_outer_loop:
inc bx
jmp outer_loop
done:
xor si, si
print_loop:
mov al, [array + si]
add al, '0'
mov [output], al
mov ah, 09h
lea dx, [output]
int 21h
inc si
mov al, [array_size]
cmp si, al
jge print_loop
Why does NASM give me these errors?
Error on line 23: Invalid combination of opcode and operands
Error on line 31: Invalid combination of opcode and operands
Error on line 66: Invalid combination of opcode and operands
The concerned lines read:
cmp bx, cl
cmp si, al
cmp si, al
Upvotes: 1
Views: 29
Reputation: 39506
This error simply means that the size of the leftmost operand (destination) is not equal to the size of the rightmost operand (source). The cmp
instruction (like most other instructions) can't deal with such a mismatch.
In your program this is easiest to resolve by declaring array_size a 16-bit quantity: array_size dw 9
, accompanied by loading to AX of course!
So it's a mismatch between operands, but why then does the error message mention "Invalid combination of opcode and operands"?
That is because a few instructions do allow this mismatch between the operands. Notably the movzx
and movsx
instructions can accept it. eg. movzx bx, cl
will copy CL into BL and also zero BH.
mov [temp], al mov [array + si], dl mov al, [temp] mov [array + si + 1], al
Please note that for the swapping part you don't need that temp variable:
mov [array + si], dl
mov [array + si + 1], al
Also note that with output resb 2
and having the print_loop only write to the first one of these two bytes (mov [output], al
), the screen will display a lot of garbage. Solve this by adding a $ character as is required by the DOS.PrintString function 09h.
print_loop:
mov al, [array + si]
add al, '0'
mov ah, "$"
mov [output], ax
Upvotes: 0