MSVC环境下如何计算C语言两个代码标签间的操作码字节数
MSVC平台计算代码段字节数的实现方案
MSVC不支持直接对C代码内的标签做减法运算,是因为C标准未定义标签指针的算术操作规则,可通过以下两种简便方案实现需求:
方案1:32位x86环境内嵌汇编实现
直接在目标代码段前后加汇编标签,通过内嵌汇编计算偏移:
#include <stdio.h> #include <windows.h> int main() { __asm jmp_code_start: // 此处放入你要统计的汇编指令,示例如下 __asm jmp eax __asm nop __asm xor eax, eax __asm jmp_code_finish: DWORD code_len = 0; __asm { mov eax, offset jmp_code_finish sub eax, offset jmp_code_start mov code_len, eax } printf("代码段总长度:%d 字节\n", code_len); return 0; }
方案2:64位环境裸函数拆分实现
64位MSVC不支持内嵌汇编,将目标代码段封装为无编译器额外插入指令的裸函数,通过函数指针减法计算长度:
#include <stdio.h> #include <stdint.h> // 目标代码段起始:裸函数无自动生成的栈帧、ret以外的额外指令 __declspec(naked) void jmp_code_start() { __asm { jmp rax nop xor rax, rax ret } } // 目标代码段结束标记,空裸函数即可 __declspec(naked) void jmp_code_finish() {} int main() { size_t code_len = (uintptr_t)jmp_code_finish - (uintptr_t)jmp_code_start; printf("代码段总长度:%zd 字节\n", code_len); return 0; }
注意事项
- 64位方案编译时必须关闭MSVC的
/Gy(函数级别链接)选项,改为/Gy-,避免编译器调整两个裸函数的内存排布顺序、插入间隔字节 - 裸函数内仅可放入你需要统计的汇编指令,不要添加C语言逻辑,避免编译器插入额外的指令影响长度统计结果
- 如果要统计的代码段原本在普通函数内部,只需将对应逻辑抽离为独立的裸函数即可正常计算长度
内容的提问来源于stack exchange,提问作者vengy
相关产品推荐
相关产品推荐

