You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于AT&T汇编语法中两种间接JMP指令写法差异的技术咨询

AT&T汇编中两段间接跳转代码的区别解析

这个问题的核心在于AT&T汇编语法里符号地址的取值方式间接跳转的语义,我来给你拆解清楚:

第一段代码:mov $main, %eax; jmp *%eax

咱们一步步看执行逻辑:

  1. mov $main, %eax:这里的$表示取立即数,也就是把标签main对应的内存地址值(比如0x080483e0)直接加载到%eax寄存器里。简单说,就是让%eax存着main代码段的入口地址。
  2. jmp *%eax*是间接跳转的标记,意思是“跳转到寄存器里存储的地址指向的位置”。这里就是跳转到%eax里存的main地址,最终效果和直接写jmp main(直接跳转)完全一样,只是多了一步寄存器中转的操作。

第二段代码:jmp *main

这段的逻辑就完全不同了:
jmp *main里的*同样标记间接跳转,但这里的操作数是符号main,AT&T汇编会把它解析为“去main对应的内存地址里读取内容,把这个内容当作跳转的目标地址”。

举个例子更直观:

  • 如果main是代码段的标签,那它对应的地址里存储的是指令的机器码(比如第一条指令是push %ebp,机器码是0x55)。这时候执行jmp *main,会把这个机器码(比如32位下是0x55xxxxxx)当成地址去跳转,这显然是错误的,大概率会触发程序崩溃。
  • 只有当main是一个函数指针变量(比如在.data段定义的.long main,也就是专门存main地址的变量)时,jmp *main才是正确的——它会读取这个变量里存的main地址,然后跳过去。

一句话总结

  • mov $main, %eax; jmp *%eax:是把main的地址给寄存器,再通过寄存器跳转到main本身,等价于直接跳转main
  • jmp *main:是把main地址里存的数据当作目标地址跳转,只有当main是指针变量时才合理。

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

火山引擎 最新活动