我尝试使用write syscall
来重现putchar
函数打印单个字符的行为。我的代码如下所示,
asm_putchar:
push rbp
mov rbp, rsp
mov r8, rdi
call:
mov rax, 1
mov rdi, 1
mov rsi, r8
mov rdx, 1
syscall
return:
mov rsp, rbp
pop rbp
ret
1条答案
按热度按时间zzlelutf1#
从
man 2 write
中,您可以看到write
的签名是,它接受一个指向内存中缓冲区的指针(
const void *buf
),但不能通过值传递char
,所以必须将其存储到内存中并传递一个指针。(Don不要一次打印一个字符,除非你只有一个字符要打印,这是非常低效的。在内存中构造一个缓冲区并打印它。例如,x86 - 64 Linux NASM函数:如何在汇编级编程中打印一个整数而不从c库中打印?(itoa,整数到十进制ASCII字符串)
GCC的NASM版本:内联程序集中的putchar(char):
如果你在RSI中传递了一个无效的指针,比如
'2'
(整数50
),系统调用将在RAX中返回-EFAULT
(-14
)。(内核在指向系统调用的坏指针上返回错误代码,而不是像你在用户空间中deref那样传递SIGSEGV)。另请参见What are the return values of system calls in Assembly?
在玩具程序/实验中,您应该在
strace ./a.out
下运行它们,而不是编写代码来检查返回值,特别是如果您编写自己的_start
而不使用libc,那么在启动过程中不会有任何其他系统调用,您自己也不会这样做,因此非常容易读取输出。How should strace be used?