如何在仅接收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 therdiregister. We savercxbecause 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 scasbto scan the string for the null terminator. This instruction incrementsrdiuntil it hits the byte inrax(0, our null terminator) orrcxreaches 0. Afterward, we invertrcxand decrement once to get the actual length of the string (excluding the null byte). - System Calls: The
writesyscall uses number1(stored inrax). 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
.dataso 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:
- Assemble the NASM file:
nasm -f elf64 say_something.asm -o say_something.o - Compile your C main program:
gcc -c main.c -o main.o - Link the two object files into an executable:
gcc main.o say_something.o -o say_it - Run the program:
./say_it
You'll see this output:
First line. Second sentence on another line.
内容的提问来源于stack exchange,提问作者user2266705
相关产品推荐
相关产品推荐

