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

x64汇编中获取Windows API与本地函数地址的指令差异问询

打印Windows API与本地函数地址时,汇编为何用mov和lea两种指令?

我在Windows x64环境下用C语言学习底层时发现一个问题:打印Windows API CreateFileW 和本地函数 addfunc 的地址时,生成的汇编指令分别用了mov和lea,想知道两者的差异和原因。

对应的汇编代码如下:

printf("%x\n", CreateFileW);
00007FF60365276C  mov         rdx,qword ptr [__imp_CreateFileW (07FF603663000h)]  
00007FF603652773  lea         rcx,[string "%x\n" (07FF60365BEA0h)]  
00007FF60365277A  call        printf (07FF603651208h)  
    printf("%x\n", addfunc);
00007FF60365277F  lea         rdx,[addfunc (07FF60365137Fh)]  
00007FF603652786  lea         rcx,[string "%x\n" (07FF60365BEA0h)]  
00007FF60365278D  call        printf (07FF603651208h)  

核心差异:mov与lea的本质区别

  • mov:从指定内存地址读取数据到寄存器,是"读内存"操作。
  • lea:计算指定内存符号的地址值并放到寄存器,不实际读取内存内容,只是做地址计算。

两种指令的使用原因

1. Windows API用mov的原因

Windows API属于动态链接库(如kernel32.dll)中的函数,编译程序时无法确定其真实内存地址:

  • 程序通过**导入表(Import Table)**管理这些外部函数,__imp_CreateFileW是导入表中的一个指针位置。
  • 程序加载时,系统会将这个指针填充为CreateFileW在内存中的真实地址。
  • 用mov rdx, qword ptr [__imp_CreateFileW],就是读取这个指针指向的真实函数地址,作为参数传给printf。

2. 本地函数用lea的原因

本地函数addfunc属于当前程序的编译单元,编译/链接阶段就已经确定了它的内存地址:

  • lea rdx, [addfunc]直接计算出addfunc的地址值,将这个地址存入rdx作为参数。
  • 编译器选择lea而非mov rdx, addfunc(也可实现),是因为lea支持RIP相对寻址(x64下默认的寻址方式),编码更紧凑高效,或符合编译器的优化策略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:06:06