You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86-64架构下switch语句对应汇编跳转表代码的疑问解析

解析x86-64汇编中addq %rcx, %rax的作用

对应的C源码

void switch_eg(long x, long n, long* dest) {
    long val = x;
    switch(n) {
        case 0: val *= 13; break;
        case 2: val += 10;
        case 3: val += 11; break;
        case 4:
        case 6: val += 11; break;
        default: val = 0;
    }
    *dest = val;
}

对应的x86-64汇编代码

.LFB0:
// x in %rdi, n in %rsi, *dest in %rdx
cmpq $6, %rsi
ja .L8 // if n > 6, switch->default
-------------------------
leaq .L4(%rip), %rcx
movslq (%rcx,%rsi,4), %rax
addq %rcx, %rax
jmp *%rax
-------------------------
.L4:
.long .L3-.L4 // case 0
.long .L8-.L4 // case 1
.long .L5-.L4 // case 2
.long .L6-.L4 // case 3
.long .L7-.L4 // case 4
.long .L8-.L4 // case 5
.long .L7-.L4 // case 6
.L3:
leaq (%rdi,%rdi,2), %rax // %rax = 3 * val
leaq (%rdi,%rax,4), %rdi // val = 4 * 3 * val + val = 13val
jmp .L2 // break
.L5:
addq $10, %rdi // val += 10
.L6:
addq $11, %rdi // val += 11
.L2:
movq %rdi, (%rdx) // *dest = val
ret // return
.L7:
addq $11, %rdi // val += 11
jmp .L2 // break
.L8:
movl $0, %edi // val = 0
jmp .L2 // break

用户疑问

我对上述汇编中标记段的代码存在疑问:
我理解leaq .L4(%rip), %rcx的作用是将跳转表数组的首地址存入%rcx寄存器;movslq (%rcx,%rsi,4), %rax是将跳转表中对应n的数组元素值存入%rax寄存器,该元素应为对应case操作的地址偏移。但我不清楚addq %rcx, %rax这句指令的具体含义,希望能得到专业的解释。


解答

这是因为跳转表.L4里存储的不是绝对地址,而是相对于跳转表首地址.L4的偏移量,我们需要把这个偏移量转换成实际的内存地址才能完成跳转。我来一步步拆解逻辑:

  1. leaq .L4(%rip), %rcx:通过RIP相对寻址计算出跳转表.L4在内存中的绝对地址,存入%rcx。x86-64下编译器默认生成位置无关代码(PIC),这种方式能保证程序不管被加载到内存的哪个位置,都能正确找到跳转表的位置。
  2. movslq (%rcx,%rsi,4), %rax:从跳转表中取出第n个元素(每个元素是4字节的.long类型,所以用%rsi*4作为偏移量定位),再通过movslq把32位的有符号偏移量扩展为64位长整型存入%rax。你说得没错,这个元素就是对应case代码块相对于.L4的地址差值,比如.L3-.L4就是.L3地址减去.L4地址的结果。
  3. addq %rcx, %rax:把跳转表的绝对地址%rcx和偏移量%rax相加,得到的就是对应case代码块的绝对内存地址。举个例子,如果%rax里存的是.L3-.L4,加上%rcx(也就是.L4的地址),最终结果就是.L3的实际运行地址。

这种设计的核心目的是保证代码的位置无关性——不管程序被加载到内存的哪个区域,只要通过「表基地址+偏移量」的计算,就能得到正确的跳转目标,让代码可以在不同的内存地址空间正常运行。最后执行jmp *%rax,就能直接跳转到对应的case处理逻辑了。

内容的提问来源于stack exchange,提问作者solego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:47:40