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

如何在仅接收char*参数的x86_64函数中调用sys_write?

Hey there, let's get that say_something() assembly function working for your x86_64 Linux setup with NASM. I'll walk you through a complete, functional implementation that plays nicely with your C main program, plus break down how everything fits together.

Complete NASM Assembly Code
section .text
    global say_something   ; Make the function visible to the linker

; void say_something(char *str)
; Input: RDI = pointer to the input string
say_something:
    ; Save registers we'll modify (per System V ABI rules)
    push rdi
    push rcx

    ; Calculate the length of the input string
    xor rax, rax           ; Set RAX to 0 (looking for null terminator)
    mov rcx, -1            ; Initialize RCX to max value for repne scasb
    repne scasb            ; Scan string until null terminator is found
    not rcx                ; Invert RCX to get length, then subtract 1 to exclude null byte
    dec rcx

    ; Write the input string to stdout
    mov rax, 1             ; Syscall number for write()
    mov rsi, [rsp+8]       ; Restore original string pointer from stack
    mov rdi, 1             ; File descriptor 1 = stdout
    mov rdx, rcx           ; Pass the calculated string length
    syscall                ; Invoke the system call

    ; Write a newline character to stdout
    mov rax, 1             ; Reuse write syscall
    mov rdi, 1             ; stdout again
    mov rsi, newline       ; Pointer to our newline constant
    mov rdx, 1             ; Newline is 1 byte long
    syscall

    ; Restore saved registers and return
    pop rcx
    pop rdi
    ret

section .data
    newline db 0xA         ; ASCII newline character (10)
Key Details & Explanations
  • x86_64 System V ABI Compliance: On Linux, the first function argument (char *str) gets passed in the rdi register. We save rcx because it's a non-volatile register— the ABI requires us to preserve it if we modify it in our function.
  • String Length Calculation: We use repne scasb to scan the string for the null terminator. This instruction increments rdi until it hits the byte in rax (0, our null terminator) or rcx reaches 0. Afterward, we invert rcx and decrement once to get the actual length of the string (excluding the null byte).
  • System Calls: The write syscall uses number 1 (stored in rax). We pass stdout as the file descriptor (rdi=1), the string pointer (rsi), and length (rdx) for two write operations—first the input string, then the newline.
  • Data Section: We store the newline character in .data so we have a constant, accessible pointer to it for the second write call.
Compilation & Running the Program

To build and test the code, run these commands in your terminal:

  1. Assemble the NASM file:
    nasm -f elf64 say_something.asm -o say_something.o
    
  2. Compile your C main program:
    gcc -c main.c -o main.o
    
  3. Link the two object files into an executable:
    gcc main.o say_something.o -o say_it
    
  4. Run the program:
    ./say_it
    

You'll see this output:

First line.
Second sentence on another line.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:10:35