我刚从这些video教程开始在linux上教自己的x86汇编。 早期教你如何使用写入系统调用来打印存储在数据部分的string。 是否可以使用写入系统调用打印存储在堆栈中的string。 这是我写的代码尝试做这似乎并不工作。
.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,但如果我通过存储在数据段中的string,ABC被打印。 我做错了什么,或者你不能这样做。 任何帮助明白。
你的系统调用号码似乎没有问题。
从你使用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使用以下寄存器作为参数: rdi
, rsi
, rdx
, r10
, r8
, r9
。
也许你正在试图在x86-64上执行系统调用,就像他们在i386上完成的一样,并期望它是相同的?