assembly 推送操作上出现“错误:未指定操作大小”,程序集x86

voase2hg  于 2023-01-09  发布在  其他
关注(0)|答案(1)|浏览(160)

我正在尝试编写一个简单的x86程序来反转一个字符串,在这个例子中:“再见”。

section .data
        msg db "ciao"
        len equ $ - msg

section .text
global _start
_start:
        lea eax, [msg]
        mov ebx, len
        add eax, ebx-1
reverseloop:
        push [eax]
        sub eax, 1
        cmp eax, [msg]
        jl reverseloop

当我试图组装它时,我得到了错误:
主系统:14:错误:未指定操作大小
因此,我尝试指定大小,将第14行修改为:

push byte [eax]

现在我得到了错误:
主系统:14:错误:操作码和操作数的组合无效
我真的不明白这有什么问题。
我用来编译的命令是:
nasm -f elf 32主文件. asm-o主文件.o

wqsoz72f

wqsoz72f1#

push [eax]

NASM不知道要压入的内存操作数的大小。您需要将其指定为push dword [eax]
不能使用push byte [eax],因为堆栈操作不处理单个字节。

add eax, ebx-1

这是您的下一个错误!源操作数ebx-1无效。
您可以首先递减EBX,然后将其添加到EAX,但是正如我将在下面说明的,您不需要这个递减。

cmp eax, [msg]
jl reverseloop

这也不是你想要的,cmp比较EAX和内存中的一个双字,但是你想要这是地址之间的比较,使用cmp eax, msg
为了对字符串的所有字符继续循环,只要EAX中的地址是GreaterOrEqualmsg,就需要有条件地跳转。

mov   eax, msg
  add   eax, len
reverseloop:
  dec   eax
  movzx ebx, byte [eax]
  push  ebx
  cmp   eax, msg
  ja    reverseloop

现在我看不出这段代码会如何反转任何东西,字符以它们在内存中的顺序到达堆栈(当然,中间穿插了一些零字节)。

mov   eax, msg
  mov   ecx, len
reverseloop1:
  movzx ebx, byte [eax]
  push  ebx
  inc   eax
  dec   ecx
  jnz   reverseloop1

  mov   eax, msg
  mov   ecx, len
reverseloop2:
  pop   ebx
  mov   [eax], bl
  inc   eax
  dec   ecx
  jnz   reverseloop2

不使用堆栈的解决方案是存在的,而且通常会更好。

相关问题