汇编程序从堆栈中写入字符

时间:2018-01-18 17:21:41

标签: linux assembly x86 gas att

我正在尝试在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设置为写入stdout的值,并将ecx设置为堆栈指针,以便它写入堆栈上的内容,而edx是堆栈上的内容的长度(即3)。当我运行它时,绝对没有任何反应。你能帮助我理解我做错了什么以及这里发生了什么事吗?

1 个答案:

答案 0 :(得分:3)

每条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 字符是没有意义的(您实际上是将它发送给{ {1}})。