I wrote this code to compare two strings and print string2
, if the code strings are the same:
enter:
pusha
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
popa
mov di, reserved_string
mov bx, string2
jmp loop1
loop1:
cmp di, si
je middle_loop1
cmp [di], [bx] ; error: invalid combination of opcode and operands
jne go_back_loop1
inc di
inc bx
jmp loop1
go_back_loop1:
mov si, reserved_string
jmp key_press
middle_loop1:
mov bx, string2
pusha
jmp print_ping
print_ping:
cmp [bx], 0 ; error: operation size not specified
je go_back_print_ping
mov ah, 0x0e
mov al, [bx]
int 0x10
inc bx
jmp print_ping
go_back_print_ping:
popa
jmp key_press
It does not compile and I get errors about two of the lines. I don't know how to fix the first problem, as I should be able to compare the two values.
Solved: The instruction does not support two dereferenced addresses.
cmp [di], [bx] ; error: invalid combination of opcode and operands
The cmp
instruction does not allow 2 memory operands. As @Jester proposed in a comment, you could write this as:
mov al, [di]
cmp al, [bx]
jne go_back_loop1
Alternatively, you could use the cmpsb
instruction. It just needs using SI instead of BX, and it does not require mentioning any operands as these are implied. Additionally and if it is not already the case, for your present code the direction flag should be cleared and your ES segment register should be equal to your DS segment register.
cmpsb ; Intel `cmps byte ptr [si], [di]`
jne go_back_loop1
cmp [bx], 0 ; error: operation size not specified
Here NASM does not know whether the datum at the address BX is a byte, word, or dword. It's your task to specify this as in:
cmp byte [bx], 0
Sometimes it so happens that you have a register with a known value like CL=0
. Then you could write the above shorter and without the assembler complaining because CL is a byte for sure:
cmp [bx], cl
loop1: cmp di, si je middle_loop1
This cmp
compares the addresses of both strings. Normally, these will always be different from each other and the loop also modifies them in sync. This cmp
does not work to end the loop correctly. What you need is looking for the terminating zero:
loop1:
mov al, [di]
cmp al, [bx]
jne go_back_loop1 ; different
inc di
inc bx
cmp al, 0 ; terminating zeroes
jne loop1
jmp middle_loop1 ; identical
jmp loop1 loop1:
jmp print_ping print_ping:
Jumps like these are redundant. The execution can just fall through in the labeled address.