【发布时间】:2021-02-25 02:09:55
【问题描述】:
在 Ubuntu 20 上,在 x86-assembly 中,我尝试使用 write 系统调用将字符串 pushed 输出到堆栈中。堆栈中的小端十六进制字节push 是 ASCII 中的 "hello world"。我的目标是仅从堆栈中输出字符串。为什么?进一步了解堆栈以及参数如何通过寄存器传递给系统调用/函数。
根据我的基本理解,我应该将push 的参数放入堆栈,mov 将esp 寄存器(指向堆栈的顶部)按write 所需参数的顺序放入寄存器。
这是我的尝试(没有输出):
; compile: nasm -f elf32 -g test.asm && ld -melf_i386 test.o -o test
section .text
global _start
_start:
xor eax, eax
push 0xc
mov ebx, esp
push eax
push 0x00646c72
push 0x6f77206f
push 0x6c6c6568
mov ecx, esp
mov edx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
预期输出:
hello world
如何更正我的代码以显示预期的输出?我做错了什么?
【问题讨论】:
-
作为开始,stackoverflow.com/questions/2535989/…。您将所有参数都放在错误的寄存器中。您应该在 eax 中具有系统调用号 (4),在 ebx 中具有文件描述符 (1),在 ecx 中具有数据指针(您正确的那个),以及 edx 中的字节数 (11)。我不知道你从哪里得到你所拥有的信息,但这完全是假的。
-
另外,你可能想在写完之后调用exit系统调用,否则你的程序接下来要做的就是执行垃圾和崩溃。
-
我看到了,我修改了代码,还是没有输出。
-
你现在打电话给
write(crazy number, buffer, 1)。你还没有把文件描述符放到ebx里面,edx里面的字节数是1。 -
哦,
push 0xc应该是长度计数吗?它根本不属于堆栈。系统调用遵循与函数调用不同的约定;一切都在寄存器中,而不是在堆栈中。不过,我认为它应该是 11 或 0xb,因为写入尾随空字节没有意义。
标签: string assembly x86 system-calls write