为何Rust中match2函数的汇编代码会将edi寄存器与1比较?
问题
给出以下Rust代码并以-C opt-level=3编译:
#[no_mangle] pub fn match1(num: i32) -> i32 { if num == 10 {99} else {11} } #[no_mangle] pub fn match2(num: Option<i32>) -> i32 { match num { Some(a) => a, _ => 11 } }
生成的汇编代码如下:
match1: cmp edi, 10 mov ecx, 99 mov eax, 11 cmove eax, ecx ret match2: cmp edi, 1 mov eax, 11 cmove eax, esi ret
为什么match2的汇编代码中会将edi寄存器与1进行比较?
解答
这是因为在x86-64的System V调用约定下,Rust的Option<T>类型采用标签+值的内存布局:
- 当
Option为None时,标签值是0; - 当
Option为Some(a)时,标签值是1,同时被包裹的a的值会存入另一个寄存器(这里是esi)。
函数match2的参数num: Option<i32>在调用时,标签部分会传入edi寄存器,Some包裹的i32值传入esi寄存器。汇编里的cmp edi, 1就是判断这个Option是否为Some变体:如果相等(即Some),就通过cmove把esi里的值放到返回寄存器eax中;否则返回默认值11。
内容的提问来源于stack exchange,提问作者gekomad
相关产品推荐
相关产品推荐

