x86 程序集 pushl/popl 不适用于“错误:后缀或操作数无效"; [英] x86 Assembly pushl/popl don't work with "Error: suffix or operands invalid"
问题描述
我是汇编编程的新手,正在使用 GNU 汇编器在 Ubuntu x86_64 桌面上完成Programming Ground Upv2.20.1.
I'm a newbie to assembly programming, working through Programming Ground Up on an Ubuntu x86_64 desktop with GNU assembler v2.20.1.
我已经能够组装/链接执行我的代码,直到我开始使用 pushl/popl 指令来操作堆栈.以下代码无法组装:
I've been able to assemble/link execute my code, up until I get to using pushl/popl instructions for manipulating the stack. The following code fails to assemble:
.section .data # empty
.section .text
.globl _start
_start:
pushl $1 # push the value 1 onto the stack
popl %eax # pop 1 off the stack and into the %eax register
int $0x80 # exit the program with exit code '1'
使用as test.s -o test.o",这些错误出现在终端上并且没有创建test.o:
Using "as test.s -o test.o", these errors appear on the terminal and test.o is not created:
test.s: Assembler messages:
test.s:9: Error: suffix or operands invalid for 'push'
test.s:10: Error: suffix or operands invalid for 'popl'
我检查了文档,我用于 pushl 和 popl 的操作数是有效的.这不完全是一个调试问题——那么我的代码有什么问题?还是我的汇编器?
I've checked the documentation, and the operands I'm using for pushl and popl are valid. This isn't exactly a debugging question--so what's wrong with my code? Or is it my assembler?
推荐答案
在 64 位模式下,您无法推送和弹出 32 位值;你需要 pushq
和 popq
.
In 64-bit mode you cannot push and pop 32-bit values; you need pushq
and popq
.
此外,您将无法通过这种方式正确退出.在 32 位 x86 上,您需要将 %eax
设置为 1 以选择 exit()
系统调用,和设置 %ebx
到您真正想要的退出代码.在 64 位 x86(这就是您使用的)上,约定是不同的:exit()
的系统调用号是 60,而不是 1;第一个系统调用参数进入%rdi
,而不是%rbx
;系统调用操作码不是 int $0x80
而是特殊的、仅限 x86-64 的操作码 syscall
.
Also, you will not get a proper exit this way. On 32-bit x86, you would need to set %eax
to 1 to select the exit()
system call, and set %ebx
to the exit code you actually wish. On 64-bit x86 (that's what you are using), conventions are different: the system call number for exit()
is 60, not 1; the first system call parameter goes in %rdi
, not %rbx
; the system-call invocation opcode is not int $0x80
but the special, x86-64-only opcode syscall
.
导致:
.section .data
.section .text
.globl _start
_start:
pushq $60
popq %rax
pushq $1
popq %rdi
syscall
(每个push
/pop
序列都可以用一个简单的mov
替换(比如mov $60, %eax
>) 当然;我想您正在尝试显式测试 push
和 pop
,优化代码大小,或避免 0
字节机器代码(用于漏洞利用负载))
(each push
/pop
sequence can be replaced with a simple mov
(like mov $60, %eax
) of course; I suppose that you are trying to explicitly test push
and pop
, optimize for code-size, or avoid 0
bytes in the machine code (for an exploit payload))
相关:
这篇关于x86 程序集 pushl/popl 不适用于“错误:后缀或操作数无效";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!