x86-64汇编程序运行终端无输出及寄存器替换后失效的问题咨询
Hey there! Let's work through your two issues one by one—first figuring out why your assembly program isn't producing any output, then explaining why swapping rcx with rsp breaks everything.
Your code has a few critical bugs that are preventing it from working as expected:
You're comparing variable addresses, not their values
When you domov rax, first_number, you're loading the memory address of thefirst_numbervariable intorax, not the value it stores. Same withmov rdi, second_number—you're comparing the fixed compile-time addresses of the two variables instead of their contents. If you wanted to compare numeric values, define them as numeric constants (e.g.,first_number: dq 50instead ofdq '50') and load their values withmov rax, [first_number].Invalid memory access in the write syscall
When you domov rcx, '1', you're putting the ASCII value of '1' (0x31) intorcx. Thenmov rsi, [rcx]tries to read from memory address 0x31—which is in a reserved kernel memory region your user-space program can't access. This either causes a crash or feeds garbage data to thewritesyscall, resulting in no visible output.
Additionally, yourwriteparameters are wrong: you're telling it to output 8 bytes (rdx=8), but you only want to print a single character. You should setrdx=1, and pointrsito a valid memory location containing your output character (like a variable in the.datasection).Syntax errors from full-width quotes
Your code uses Chinese full-width quotes (‘1’,‘0‘) instead of English single quotes ('1','0'). NASM won't recognize these characters and will throw compilation errors—make sure to use standard ASCII quotes.
Fixed Example Code
Here's a corrected version that compares numeric values and prints the expected result:
section .data first_number: dq 50 ; Store numeric value 50, not ASCII string second_number: dq 40 ; Store numeric value 40 result_true: db '1', 0xA ; '1' plus newline for clean output result_false: db '0', 0xA ; '0' plus newline section .text global _start _start: mov rax, [first_number] ; Load actual value of first_number mov rdi, [second_number] ; Load actual value of second_number cmp rax, rdi jae .true jb .false .true: mov rsi, result_true ; Point to the '1' string mov rdx, 2 ; Length: '1' + newline = 2 bytes jmp .execution .false: mov rsi, result_false ; Point to the '0' string mov rdx, 2 ; Length: '0' + newline = 2 bytes jmp .execution .execution: mov rax, 1 ; Syscall number for write mov rdi, 1 ; File descriptor (stdout) syscall ; Invoke write mov rax, 60 ; Syscall number for exit xor rdi, rdi ; Exit code 0 syscall ; Invoke exit
Compile and run it with your existing command:
nasm -felf64 example.asm -o example.o && ld example.o -o example && ./example
rcx with rsp Breaks the Program The rsp register is the stack pointer—a special register that tracks the top of your program's stack. The stack is used for critical operations like storing return addresses, preserving register values, and managing function calls.
- When you do
mov rsp, '1', you're overwriting the stack pointer with the ASCII value 0x31. This completely breaks the stack's structure—your program can no longer handle stack operations correctly, which will almost certainly cause a crash before it reaches thewritesyscall. - Even if the program didn't crash,
mov rsi, [rsp]would still try to read from address 0x31, which is invalid user-space memory—repeating the same invalid access bug as withrcx.
Never overwrite rsp with arbitrary values unless you're explicitly managing stack space (e.g., allocating room for local variables with sub rsp, 16).
内容的提问来源于stack exchange,提问作者Ruslan

