x86 程序集 pushl/popl 不适用于“错误:后缀或操作数无效"; [英] x86 Assembly pushl/popl don't work with "Error: suffix or operands invalid"

查看:21
本文介绍了x86 程序集 pushl/popl 不适用于“错误:后缀或操作数无效";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是汇编编程的新手,正在使用 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 位值;你需要 pushqpopq.

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>) 当然;我想您正在尝试显式测试 pushpop,优化代码大小,或避免 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆