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

2024-10-14 08:40:00
admin
原创
234
摘要:问题描述:我正在尝试使用 writesyscall来重现putchar打印单个字符的函数行为。我的代码如下,asm_putchar: push rbp mov rbp, rsp mov r8, rdi call: mov rax, 1 mov rd...

问题描述:

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

解决方案 1:

从中man 2 write,你可以看到签名是write

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

它需要一个指向内存缓冲区的指针 ( const void *buf)。您不能通过char值传递它,因此您必须将其存储到内存中并传递一个指针。

write(除非只有一个字符需要打印,否则不要一次打印一个字符,这确实效率低下,这就是 C stdio 通常会缓冲 I/O 的原因。在内存中构造一个缓冲区并打印:例如这个 x86-64 Linux NASM 函数:如何在没有 c 库中的 printf 的情况下在汇编级编程中打印一个整数?(itoa,整数到十进制 ASCII 字符串))

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:
    lea     rsi, [rsp-4]          ; RSI = buf in the red zone (below RSP)
    mov    [rsi], edi             ; store the char from RDI into it

    mov     eax, 1                ; __NR_write syscall number from unistd_64.h
    mov     edi, 1                ; EDI = fd=1 = stdout
    ; RSI = buf set earlier, before overwriting the char in EDI
    mov     edx, eax              ; RDX = len = 1  happens to be the same as fd and call #
    syscall                    ; rax = write(1, buf, 1)
    ret

我们实际上只需要 1 字节存储,例如mov [rsp-1], dil,但 4 字节存储可节省一个字节的代码大小。这int putchar(int)意味着调用者应该写入完整的寄存器,因此即使在旧 CPU 上我们也不会出现部分寄存器停顿。


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

另请参阅汇编中系统调用的返回值是什么?

在玩具程序/实验中,您无需编写代码来检查返回值,而只需在 下运行它们即可strace ./a.out。如果您编写的程序_start不使用 libc,则在启动期间不会有任何其他您自己未执行的系统调用,因此读取输出非常容易,否则在您的代码之前会有一堆由 libc 执行的启动系统调用。strace 应该如何使用?

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1267  
  IPD(Integrated Product Development)即集成产品开发,是一套先进的、成熟的产品开发管理理念、模式和方法。随着市场竞争的日益激烈,企业对于提升产品开发效率、降低成本、提高产品质量的需求愈发迫切,IPD 项目管理咨询市场也迎来了广阔的发展空间。深入探讨 IPD 项目管理咨询的市场需求与发展,...
IPD集成产品开发流程   27  
  IPD(Integrated Product Development)产品开发流程是一套先进的、被广泛应用的产品开发管理体系,它涵盖了从产品概念产生到产品推向市场并持续优化的全过程。通过将市场、研发、生产、销售等多个环节紧密整合,IPD旨在提高产品开发的效率、质量,降低成本,增强企业的市场竞争力。深入了解IPD产品开发...
IPD流程中TR   31  
  IPD(Integrated Product Development)测试流程是确保产品质量、提升研发效率的关键环节。它贯穿于产品从概念到上市的整个生命周期,对企业的成功至关重要。深入理解IPD测试流程的核心要点,有助于企业优化研发过程,打造更具竞争力的产品。以下将详细阐述IPD测试流程的三大核心要点。测试策略规划测试...
华为IPD   26  
  华为作为全球知名的科技企业,其成功背后的管理体系备受关注。IPD(集成产品开发)流程作为华为核心的产品开发管理模式,在创新管理与技术突破方面发挥了至关重要的作用。深入剖析华为 IPD 流程中的创新管理与技术突破,对于众多企业探索自身发展路径具有重要的借鉴意义。IPD 流程概述IPD 流程是一种先进的产品开发管理理念和方...
TR评审   26  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用