assembly “错误:操作码和操作数的组合无效”,当比较“取消引用”地址时

4smxwvx5  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(144)

我写了这段代码来比较两个字符串,如果代码字符串相同,就打印string2

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

它没有编译,我得到了关于两行的错误。我不知道如何修复第一个问题,因为我应该能够比较这两个值。

5m1hhzi4

5m1hhzi41#

无法编译。

cmp [di], [bx] ; error: invalid combination of opcode and operands

cmp指令不允许2个内存操作数。正如@Jester在注解中建议的那样,您可以将其编写为:

mov  al, [di]
cmp  al, [bx]
jne  go_back_loop1

或者,您可以使用cmpsb指令。它只需要使用SI而不是BX,并且不需要提及任何操作数,因为这些操作数是隐含的。此外,如果尚未出现这种情况,则对于当前代码,方向标志应被清除,ES段寄存器应等于DS段寄存器。
一个二个一个一个
这里NASM不知道地址BX处的数据是字节、字还是双字,你的任务是按下式指定:

cmp  byte [bx], 0

有时候,你碰巧有一个寄存器,它的值是已知的,比如CL=0,那么你可以把上面的代码写得更短,而且汇编程序不会抱怨,因为CL肯定是一个字节:

cmp  [bx], cl

现在它编译了,但是它会运行吗?

loop1:
  cmp di, si
  je middle_loop1

这个cmp比较两个字符串的地址。通常,它们总是彼此不同,循环也同步修改它们。这个cmp不能正确地结束循环。你需要寻找终止零:

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

小心这些。

一个八个八个一个一个一个九个一个
像这样的跳转是多余的,执行可能会在标记的地址中失败。

相关问题