为什么 64 位 nasm 坚持使用 rsi 寄存器? (为什么我不能将 "hello world" 放入 rcx 寄存器?)
Why is 64 bit nasm insisting on the rsi register ? (why can't I put "hello world" into rcx register?)
我有一个“hello world”程序的 x86 汇编代码。
global _start
section .text
_start:
mov eax, 1 ; system call for write
mov ebx, 1 ; file handle 1 is stdout
mov ecx, message ; address of string to output
mov edx, message_len ; length of the string
syscall ; invoke operating system to do the write
mov eax, 60 ; system call for exit
mov ebx, 0 ; exit code 0
syscall ; invoke operating system to ex
section .data
message: db "Hello, World!!!!", 10 ; newline at the end
message_len equ $-message ; length of the string
这不能在 64 位 Linux 机器上用 nasm -felf64 hello.asm && ld hello.o && ./a.out
编译。
但是如果我改变第三行:
mov ecx, message
到 mov rsi, message
有效!
我的问题是为什么 64 位 nasm 坚持使用 rsi
寄存器?
因为我看到有人在 32 位 Arch Linux 上使用 ecx
进行编译 Linux。
x86 不使用与 x64 相同的调用约定。在 x86 中,第一个参数是 ebx,它包含描述符,ecx 包含缓冲区,edx 包含长度,eax 包含系统调用序号。
在 x64 中,第一个参数包含在 RDI 中,第二个参数包含在 RSI 中,第三个参数包含在 RDX 中,第四个参数包含在 RCX 中,而 RAX 包含系统调用的序号。
这就是您的调用在 X86 上运行但需要调整以在 X64 上运行的原因。
我有一个“hello world”程序的 x86 汇编代码。
global _start section .text _start: mov eax, 1 ; system call for write mov ebx, 1 ; file handle 1 is stdout mov ecx, message ; address of string to output mov edx, message_len ; length of the string syscall ; invoke operating system to do the write mov eax, 60 ; system call for exit mov ebx, 0 ; exit code 0 syscall ; invoke operating system to ex section .data message: db "Hello, World!!!!", 10 ; newline at the end message_len equ $-message ; length of the string
这不能在 64 位 Linux 机器上用 nasm -felf64 hello.asm && ld hello.o && ./a.out
编译。
但是如果我改变第三行:
mov ecx, message
到 mov rsi, message
有效!
我的问题是为什么 64 位 nasm 坚持使用 rsi
寄存器?
因为我看到有人在 32 位 Arch Linux 上使用 ecx
进行编译 Linux。
x86 不使用与 x64 相同的调用约定。在 x86 中,第一个参数是 ebx,它包含描述符,ecx 包含缓冲区,edx 包含长度,eax 包含系统调用序号。
在 x64 中,第一个参数包含在 RDI 中,第二个参数包含在 RSI 中,第三个参数包含在 RDX 中,第四个参数包含在 RCX 中,而 RAX 包含系统调用的序号。
这就是您的调用在 X86 上运行但需要调整以在 X64 上运行的原因。