使用 64 位 Linux 在 x86_64 的汇编中编写 putchar?

Luc*_*cas 1 linux assembly x86-64 nasm system-calls

我正在尝试使用 writesyscall来重现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
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 5

man 2 write,你可以看到writeis的签名,

ssize_t write(int fd, const void *buf, size_t count);
Run Code Online (Sandbox Code Playgroud)

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

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

GCC的 NASM 版本:内联汇编中的 putchar(char)

; 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
Run Code Online (Sandbox Code Playgroud)