Hello.
I have two functions and both of them are expected to return the given argument:
pub fn main() !void {
log.debug("{X}", .{hoge1(0xDEADBEEF)});
log.debug("{X}", .{hoge2(0xDEADBEEF)});
}
fn hoge1(arg1: u64) u64 {
return asm volatile (
\\movq %[arg1], %[ret]
: [ret] "={rax}" (-> u64),
: [arg1] "m" (arg1),
);
}
fn hoge2(arg1: u64) u64 {
return asm volatile (
\\movq (%[arg1]), %[ret]
: [ret] "={rax}" (-> u64),
: [arg1] "r" (&arg1),
);
}
hoge2()
returns 0xDEADBEEF
as expected. However, hoge1()
returns stack address. The output assembly is below:
0000000001034c50 <main.hoge1>:
1034c50: 55 push rbp
1034c51: 48 89 e5 mov rbp,rsp
1034c54: 48 83 ec 18 sub rsp,0x18
1034c58: 48 89 7d f0 mov QWORD PTR [rbp-0x10],rdi
1034c5c: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
1034c60: 48 8d 45 f8 lea rax,[rbp-0x8]
1034c64: 48 89 45 e8 mov QWORD PTR [rbp-0x18],rax
1034c68: 48 8b 45 e8 mov rax,QWORD PTR [rbp-0x18]
1034c6c: 48 83 c4 18 add rsp,0x18
1034c70: 5d pop rbp
1034c71: c3 ret
1034c72: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
1034c79: 00 00 00
1034c7c: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
0000000001034c90 <main.hoge2>:
1034c90: 55 push rbp
1034c91: 48 89 e5 mov rbp,rsp
1034c94: 48 83 ec 10 sub rsp,0x10
1034c98: 48 89 7d f0 mov QWORD PTR [rbp-0x10],rdi
1034c9c: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
1034ca0: 48 8d 45 f8 lea rax,[rbp-0x8]
1034ca4: 48 8b 00 mov rax,QWORD PTR [rax]
1034ca7: 48 83 c4 10 add rsp,0x10
1034cab: 5d pop rbp
1034cac: c3 ret
1034cad: 0f 1f 00 nop DWORD PTR [rax]
I expected that two of them are compiled to the virtually same assembly, but they are not.
I believe something in my code is wrong (I’m not familiar with asm).
I appreciate your advice.
NOTE: For your information, HERE is a C result in CompileExplorer.
NOTE: I’m using Zig 0.13.0.