syscall WRITE不会从堆栈写入数据吗?

时间:2018-11-14 13:59:44

标签: linux assembly x86-64

代码如下:

segment .text

global _start

_start:
        mov     rcx, [rsp+16]
        dec     rdx
.L1:
        inc     rdx
        cmp     al, byte [rcx+rdx]
        jnz     .L1

        mov     rax, 4
        mov     rbx, 1
        int     0x80

        mov     rax, 1
        mov     rbx, 0
        int     0x80

它将第二个参数字符串(argv [1])参数的地址移入RCX,将RDX计数字符递增直到'\ 0'并写入STDOUT_FILENO。

当我使用yasm进行编译时,请与ld链接并按以下方式运行可执行文件:

$ ./a.out somechars

预期输出为:

somechars$

($代表终端提示,缺少换行符)

但是相反,我立即看到终端提示,就像我什么也没运行,只是在空命令行中按ENTER键一样。

然后我在源代码中添加了更多行:

segment .data                 ; NEW
                              ; NEW
deb db "somechars", 0         ; NEW
                              ; NEW
segment .text

global _start

_start:
        mov     rcx, [rsp+16]
        mov     rcx, deb      ; NEW
        dec     rdx
.L1:
        inc     rdx
        cmp     al, byte [rcx+rdx]
        jnz     .L1

        mov     rax, 4
        mov     rbx, 1
        int     0x80

        mov     rax, 1
        mov     rbx, 0
        int     0x80

效果很好:

$ ./a.out somechars
somechars$

(决定键入相同的命令,尽管可以省略“ somechars”)

这是调试器说的:

(gdb) l
1   segment .data
2   
3   deb db "somechars", 0
4   
5   segment .text
6   
7   global _start
8   
9   _start:
10          mov     rcx, [rsp+16]
(gdb) b 9
Breakpoint 1 at 0x4000b0: file exp.asm, line 9.
(gdb) run somechars
Starting program: /home/polazhinets_a/work/ll/a.out somechars

Breakpoint 1, _start () at exp.asm:10
10          mov     rcx, [rsp+16]
(gdb) ni
11          mov     rcx, deb
(gdb) x/10cb $rcx
0x7fffffffe1b7:     115 's' 111 'o' 109 'm' 101 'e' 99 'c'  104 'h' 97 'a'  114 'r'
0x7fffffffe1bf:     115 's' 0 '\000'
(gdb) ni
12          dec     rdx
(gdb) x/10cb $rcx
0x6000e8:   115 's' 111 'o' 109 'm' 101 'e' 99 'c'  104 'h' 97 'a'  114 'r'
0x6000f0:   115 's' 0 '\000'
(gdb)

在两个MOV之后,RCX指向的数十个字节的数据数据之间显然没有区别,除了在第一种情况下地址为低(数据段),在第二种情况下为高地址(堆栈段)。

我知道,如果在某处存在延迟,那么READ和WRITE都不提供任何保证,并且很可能处理0个字节,但是我不是想从0x7fffff0000f8(

真正的原因是什么?

已解决

48位堆栈虚拟地址不适合32位,因此应使用SYSCALL而不是32位INT

0 个答案:

没有答案