【问题标题】:Assembly program to write character from stack汇编程序从堆栈中写入字符
【发布时间】:2018-01-18 17:21:41
【问题描述】:

我正在尝试在 AT&T 语法汇编中编写一个测试程序,将某些字符的 ascii 值推送到堆栈,然后打印它们。我的代码如下:

.text
.global main
main:
    push $0
    push $10
    push $65
    mov $4,%eax
    mov $1,%ebx
    mov %esp,%ecx
    mov $3,%edx
    int $0x80

    mov $1,%eax
    int $0x80

我希望这个程序做的是将 0、10 和 65 压入堆栈,使堆栈为 65、10、0(大写字母 A、换行符、字符串结尾)。将eaxebx 设置为写入标准输出的值,并将ecx 设置为堆栈指针,以便它写入堆栈上的内容,而edx 是堆栈上的长度(即3) .当我运行它时,绝对没有任何反应。你能帮我理解我做错了什么以及这里实际发生了什么吗?

【问题讨论】:

  • push 将 4 个字节存储到内存中(在 32 位模式下)。因此,您应该只看到您的信 A。单个push $0x0a41 也应该为您提供换行符。请注意,write() 或您的终端并不特别关心终止零,因此只需打印两个字节就足够了。
  • 使用我的初始代码,或者使用您建议的单推版本,控制台不会打印任何内容。
  • 两者都按照描述在这里工作。然后通过strace 运行您的代码。
  • 在调试器中运行,在每个push之后检查rsp/esp的值,提出质疑。如果它移动了8,您正在将这个 32b linux API 汇编源编译为 64b 二进制文件,这将不起作用,您需要使用syscall 而不是int 0x80,并修复参数(syscall 服务是不同的)。如果您没有调试器,只需尝试添加mov rax,rcx,这在 32b 模式下应该会失败,但会在 64b 模式下编译)。你绝对需要调试器,并学会使用它。
  • 如果您不小心将其编译为 64b 二进制文件:请检查此答案,为什么它不起作用:stackoverflow.com/q/46087730/4271923

标签: linux assembly x86 gnu-assembler att


【解决方案1】:

每条push 指令将 4 个字节压入堆栈。所以,这就是int 0x80 之前堆栈的样子:

   ....
----------  (highest address)
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x00  |
---------- <-- push $0
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x0A  | 
---------- <-- push $10
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x00  |
---------- 
|  0x41  |
---------- <-- push $65 <-- ESP

但是,此时您希望堆栈看起来像:

   ....
---------- 
|  0x00  |
---------- 
|  0x0A  |
---------- 
|  0x41  |
---------- <-- ESP

这可以通过将您的 push 指令替换为以下内容来实现:

push $0x0a41

即:

.text
.global main
main:
    push $0x0a41

    mov $4,%eax    ;system call write()
    mov $1,%ebx    ;file descriptor (stdout)
    mov %esp,%ecx  ;string
    mov $3,%edx    ;length of the string
    int $0x80

    mov $1,%eax
    int $0x80

edx 寄存器中你已经指定了字符串的长度(即:3),NUL 字符是没有意义的(你实际上是把它发送到stdout)。

【讨论】:

  • 使用该 push 语句并将 edx 设置为 3 也不会打印任何内容。
  • 如果您使用的是 64 位系统,则需要汇编和链接为 32 位代码才能正常工作。
  • 正确:使用gcc -m32
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 2017-12-28
相关资源
最近更新 更多