我正在尝试读取传递给我的可执行文件的文件名并使用程序集写入该文件。它编译时没有错误但在执行时失败。我的代码究竟出了什么问题?
BITS 32
segment .data
text db "text"
segment .text
global main
main:
pop ebx
pop ebx
pop ebx ; pop pointer to filename into ebx
mov eax,0x5 ;syscall open
mov ecx,0x2 ;flag read/write
int 0x80 ;call kernel
mov ebx,eax ;save returned file descriptor
mov eax,0x4 ; write syscall
mov ecx,text ;mov pointer to text into ecx
mov edx,0x4 ;string length
int 0x80 ;exit syscall
mov eax,0x1
int 0x80
答案 0 :(得分:5)
由于你是从libc调用的,你还必须记得你有回复地址,所以你可以回到那里。这与你得到的东西不同,如果你只有一个简单的汇编程序(就像很多教程!)。考虑到这一点:
pop ebx ;; pops return address to libc caller (_start usually)
pop ebx ;; pops argc
pop ebx ;; pops argv !!WAS!!: ; pop pointer to filename into ebx
以下是打印第一个参数的方法。你应该能够从那里开始(注意:我可能犯了错误):
BITS 32
section .text
global main
extern strlen
main:
pop ecx ; Return address
pop ecx ; argc
pop ecx ; argv
mov ecx, [ecx+4] ; argv[1]
push ecx
call strlen
mov edx, eax ; count
pop ecx ; buf
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
int 0x80
mov eax, 1 ; sys_exit
mov ebx, 0 ; status
int 0x80
答案 1 :(得分:2)
在进入main时:堆栈具有以下内容:
...
*envp[]
*argv[]
argc
return address
当您pop ebx
三次时,您最终会访问argv
,而不是 argv[1]
。
argv
是一个指向以NULL结尾的char *
数组的指针,所以你必须遵循间接,就像@ user786653所示。