You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法直接向sys_write传入立即数以实现标准输出的汇编调用?

关于x86_64汇编中SYS_WRITE系统调用参数的疑问

你有两段x86_64汇编代码,第一段可以正常运行:

SYS_READ equ 0
SYS_WRITE equ 1
SYS_EXIT equ 60

STDIN equ 0
STDOUT equ 1

section .data
    my_char: db 'a'

global _start

section .text
    _start:
        mov rax, SYS_WRITE
        mov rdi, STDOUT
        mov rsi, my_char
        mov rdx, 1
        syscall
        
        mov rax, SYS_EXIT
        mov rdi, 0
        syscall

但将rsi的赋值改为立即数后,代码无法运行:

SYS_READ equ 0
SYS_WRITE equ 1
SYS_EXIT equ 60

STDIN equ 0
STDOUT equ 1

global _start

section .text
    _start:
        mov rax, SYS_WRITE
        mov rdi, STDOUT
        mov rsi, 'a' ; 用立即数字节操作数替换变量
        mov rdx, 1
        syscall
        
        mov rax, SYS_EXIT
        mov rdi, 0
        syscall

你原本以为两种写法都是把rsi设为'a',只是后者没用到变量,想知道二者在内存层面的区别,以及有没有类似第二种写法的可行实现方式。


一、内存层面的核心区别

  • 第一段代码的mov rsi, my_char:这里的my_char是.data段中存储字符'a'的64位内存地址。这条指令是把该内存地址加载到rsi寄存器里,而SYS_WRITE系统调用要求rsi指向要输出数据的内存起始地址,内核会从这个地址读取1字节数据(对应rdx=1),也就是.data段里的'a',因此能正常输出。
  • 第二段代码的mov rsi, 'a':这里是把ASCII值0x61(即'a')直接加载到rsi寄存器里。此时rsi的值是0x61,并非有效内存地址——内核尝试访问地址0x61时,该区域属于进程未映射的低地址空间,会触发段错误,导致程序崩溃。

二、类似第二种写法的可行实现方式

如果不想用.data段的变量,有两种常见方法:

1. 在代码段嵌入数据,通过相对寻址访问

直接在.text段嵌入字符'a',利用rip相对寻址获取其地址:

SYS_WRITE equ 1
SYS_EXIT equ 60
STDOUT equ 1

global _start

section .text
_start:
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    lea rsi, [rel char_data] ; 获取嵌入数据的内存地址
    mov rdx, 1
    syscall

    mov rax, SYS_EXIT
    mov rdi, 0
    syscall

char_data: db 'a' ; 在代码段后直接嵌入数据

这种方式无需单独的.data段,数据与代码同段,适合存储小量数据。

2. 将字符压入栈中,用栈地址作为参数

利用栈临时存储字符,把栈指针作为rsi的参数:

SYS_WRITE equ 1
SYS_EXIT equ 60
STDOUT equ 1

global _start

section .text
_start:
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    push 'a' ; 将字符以8字节形式压入栈,栈顶即为该字符的内存地址
    mov rsi, rsp ; 栈指针rsp指向栈顶的'a'
    mov rdx, 1
    syscall
    add rsp, 8 ; 平衡栈,恢复栈指针位置

    mov rax, SYS_EXIT
    mov rdi, 0
    syscall

x86_64的栈操作按8字节对齐,push 'a'实际会把0x0000000000000061压入栈,内核读取1字节时只会取最低位的0x61(即'a'),不影响输出结果。

内容的提问来源于stack exchange,提问作者coulomb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:45:41