melissa
melissa

Reputation: 11

Multiple counts of "Invalid combination of opcode and operands" error

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

Answers (1)

Sep Roland
Sep Roland

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

Related Questions