gpt4 book ai didi

linux - 使用 64 位 Linux 在 Assembly for x86_64 中编写一个 putchar?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:55:12 26 4
gpt4 key购买 nike

我正在尝试使用 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

最佳答案

来自 man 2 write ,可以看到write的签名是,

ssize_t write(int fd, const void *buf, size_t count);

它需要一个指向内存缓冲区的指针 ( const void *buf )。你不能给它传递 char按值,所以你必须将它存储到内存并传递一个指针。

(不要一次打印一个字符,除非你只有一个字符要打印,这真的很低效。在内存中构造一个缓冲区并打印它。例如这个 x86-64 Linux NASM 函数:How do I print an integer in Assembly Level Programming without printf from the c library?)

GCC: putchar(char) in inline assembly 的 NASM 版本:

; x86-64 System V calling convention: input = byte in DIL
; clobbers: RDI, RSI, RDX, RCX, R11 (last 2 by syscall itself)
; returns: RAX = write return value: 1 for success, -1..-4095 for error
writechar:
mov byte [rsp-4], dil ; store the char from RDI

mov edi, 1 ; EDI = fd=1 = stdout
lea rsi, [rsp-4] ; RSI = buf
mov edx, edi ; RDX = len = 1
syscall ; rax = write(1, buf, 1)
ret

如果您确实在 RSI 中传递了一个无效指针,例如 '2' (整数 50 ),系统调用将返回 -EFAULT ( -14 ) 在 RAX 中。 (内核会在指向系统调用的错误指针上返回错误代码,而不是像在用户空间中取消引用时那样传递 SIGSEGV)。

另见 What are the return values of system calls in Assembly?

与其编写代码来检查返回值,在玩具程序/实验中,您应该在 strace ./a.out 下运行它们,特别是如果您正在编写自己的 _start如果没有 libc,在启动期间将不会有任何其他不是您自己创建的系统调用,因此读取输出非常容易。 How should strace be used?

关于linux - 使用 64 位 Linux 在 Assembly for x86_64 中编写一个 putchar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50681077/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com