Linux使用堆栈上的字符串写入sys调用

时间:2011-07-17 13:33:52

标签: linux assembly x86 system-calls

我刚从these视频教程开始在linux上自学x86程序集。在早期,它教你如何使用write sys-call打印存储在数据部分中的字符串。是否可以使用write syscall打印存储在堆栈中的字符串。这是我编写的代码尝试并执行此操作似乎不起作用。

.data
abc: 
    .asciz "ABC"
.text
    .globl _start

_start:
    pushq %rbp
    movq %rsp, %rbp
    subq $32, %rsp
    leaq -32(%rbp), %rdi
    movb $65, (%rdi)        #move 'A' on to stack
    addq $1, %rdi           
    movb $66, (%rdi)        #move 'B' on to stack
    addq $1, %rdi
    movb $67, (%rdi)        #move 'C' on to stack
    addq $1, %rdi
    movb $0, (%rdi)         #Null terminate  

    movq $4, %rax           #4 is write syscall
    movq $1, %rbx           #1 for stdout
    movq %rsp, %rcx         #pointer to ABC string on stack
    movq $3, %rdx           #length of string
    int $0x80

    movq $1, %rax           #exit syscall
    xorq %rbx, %rbx
    int $0x80

此程序只运行并退出而不打印ABC,但如果我传递存储在数据段中的字符串,则打印ABC。我做错了什么,或者你不能这样做。任何帮助升值。

1 个答案:

答案 0 :(得分:4)

您的系统调用号码似乎已经过时了。

从你使用movq和“r”寄存器,我猜你正在试用x86-64。看一下/usr/include/asm/unistd_64.h,我可以看到以下内容:

#define __NR_write                              1
#define __NR_stat                               4
#define __NR_exit                               60

strace同意我的意见:

$ strace ./abc
execve("./abc", ["./abc"], [/* 43 vars */]) = 0
stat("", NULL)                          = -1 EFAULT (Bad address)
write(-1698988341, NULL, 3 <unfinished ... exit status 0>

请注意,参数也是关闭的。您还使用错误的寄存器来完成其余参数。 x86-64上的调用约定AFAIK按以下顺序使用以下寄存器:rdirsirdxr10,{{1} },r8

也许你正试图在x86-64上按照在i386上完成的方式进行系统调用并期望它是一样的?