【发布时间】:2016-10-09 20:40:19
【问题描述】:
通过一些操作,我将其缩小为ret 操作的问题。我知道call 将返回地址推入堆栈;弹出再推回去违法吗?
format ELF64 executable 3
entry start
segment readable executable
start:
pop rcx ; argc
mov [argc],cl ; int -> ASCII
add [argc],'0'
push 1 argc 1
call sys_write
mov rdi,0
mov rax,60
syscall
sys_write: ; (fd,*buf,count)
pop r11
pop rdx rsi rdi
mov rax,1
syscall
push r11
ret
segment readable writable
argc rb 1
输出是:
$ ./prog
1Segmentation fault
$ _
【问题讨论】:
-
SYSCALL 破坏 r11。您几乎可以选择任何其他寄存器。但是在寄存器中传递函数参数(就像 ABI 标准调用约定那样)或者使用
mov ..., [rsp+8]读取堆栈要容易得多。 FASM 的pop rdx rsi rdi语法只是语法糖,它仍然组装成 3 条指令。这效率不高。 -
如果您使用了调试器,您可以检查寄存器值。
-
你在开玩笑吧。好吧,
r12工作了。只是我的运气。非常感谢。 -
@PeterCordes 另外,我知道它效率不高,但我想在编写宏之前为我正在编写的另一个更大的程序编写简洁的系统调用。不过感谢
rsp的建议。我从来没有想过。
标签: linux assembly return x86-64 fasm