Windows x64 上与 CS:APP x86-64 Linux 交换 long 示例函数的不同 asm
Different asm on Windows x64 from a CS:APP x86-64 Linux example function for swapping a long
我正在阅读CS:APP第3版(Ch3.pic 3.7 GAS汇编代码)
long exchange(long* xp, long y)
{
long x = *xp;
*xp = y;
return x;
}
exchange:
movq (%rdi), %rax
movq %rsi, (%rdi)
ret
我想知道为什么下面的汇编代码(1.asm:转换为nasm)不起作用?
我已经使用 c2nasm 将工作的 c 函数反汇编为 nasm 汇编源代码。与原来的组装完全不同。
main.cpp :
int main()
{
long a = 4;
// long b = exchange(&a, 3);
long b = exchange2(&a, 3);
printf("[a: %ld] [b: %ld]\n", a, b);
return 0;
}
1.asm :
BITS 64
; default rel
default abs
global exchange2
section .text
exchange2:
;;; this code does not works
;;; program output -> [a: 4] [b: 0]
mov rax, [rdi]
mov [rdi], rsi
ret
;;; this code works, generated by c2nasm.
;;; program output -> [a: 3] [b: 4]
; push rbp
; mov rbp, rsp
; sub rsp, 16
; mov qword [rbp+10H], rcx
; mov dword [rbp+18H], edx
; mov rax, qword [rbp+10H]
; mov eax, dword [rax]
; mov dword [rbp-4H], eax
; mov rax, qword [rbp+10H]
; mov edx, dword [rbp+18H]
; mov dword [rax], edx
; mov eax, dword [rbp-4H]
; leave
; ret
编辑:谢谢!
Windows x64 long long exchange(long long*, long long)
:
的工作版本
BITS 64
default rel
global _exchange2 ; Windows name-mangling prepends _ to C names
section .text
_exchange2:
mov rax, [rcx]
mov [rcx], rdx
ret
您的示例适用于 Linux、OS X 和其他非 Windows 平台(64 位 long
, RDI、RSI 中的参数...)
您为 Windows x64 编译,它使用不同的调用约定(RCX、RDX 中的参数),long
是 32 位类型。
您在编译时也禁用了优化,因此 asm 充满了 store/reload 噪音。通过优化,它基本上是相同的,但寄存器不同。
顺便说一句,您可以使用 gcc -O3 -masm=intel
来获得更接近 NASM 语法的英特尔语法汇编。 (虽然它是 不是 NASM 语法;它的寻址模式类似于 MASM,并且仍然使用 GAS 指令。)
我正在阅读CS:APP第3版(Ch3.pic 3.7 GAS汇编代码)
long exchange(long* xp, long y)
{
long x = *xp;
*xp = y;
return x;
}
exchange:
movq (%rdi), %rax
movq %rsi, (%rdi)
ret
我想知道为什么下面的汇编代码(1.asm:转换为nasm)不起作用?
我已经使用 c2nasm 将工作的 c 函数反汇编为 nasm 汇编源代码。与原来的组装完全不同。
main.cpp :
int main()
{
long a = 4;
// long b = exchange(&a, 3);
long b = exchange2(&a, 3);
printf("[a: %ld] [b: %ld]\n", a, b);
return 0;
}
1.asm :
BITS 64
; default rel
default abs
global exchange2
section .text
exchange2:
;;; this code does not works
;;; program output -> [a: 4] [b: 0]
mov rax, [rdi]
mov [rdi], rsi
ret
;;; this code works, generated by c2nasm.
;;; program output -> [a: 3] [b: 4]
; push rbp
; mov rbp, rsp
; sub rsp, 16
; mov qword [rbp+10H], rcx
; mov dword [rbp+18H], edx
; mov rax, qword [rbp+10H]
; mov eax, dword [rax]
; mov dword [rbp-4H], eax
; mov rax, qword [rbp+10H]
; mov edx, dword [rbp+18H]
; mov dword [rax], edx
; mov eax, dword [rbp-4H]
; leave
; ret
编辑:谢谢!
Windows x64 long long exchange(long long*, long long)
:
BITS 64
default rel
global _exchange2 ; Windows name-mangling prepends _ to C names
section .text
_exchange2:
mov rax, [rcx]
mov [rcx], rdx
ret
您的示例适用于 Linux、OS X 和其他非 Windows 平台(64 位 long
, RDI、RSI 中的参数...)
您为 Windows x64 编译,它使用不同的调用约定(RCX、RDX 中的参数),long
是 32 位类型。
您在编译时也禁用了优化,因此 asm 充满了 store/reload 噪音。通过优化,它基本上是相同的,但寄存器不同。
顺便说一句,您可以使用 gcc -O3 -masm=intel
来获得更接近 NASM 语法的英特尔语法汇编。 (虽然它是 不是 NASM 语法;它的寻址模式类似于 MASM,并且仍然使用 GAS 指令。)