为什么 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, messagemov 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 上运行的原因。