c - 为什么我的编译器(VS2017)选择 'CALL-JMP' 来到达子例程而不是仅仅 'CALL' ?

标签 c visual-studio assembly

C 代码:

#include <stdio.h>

int main(){
    printf("hello word!\n");
    return;
}

汇编代码:

push    offset aHelloWord ; "hello word!\n"
call    sub_41104B
add     esp, 4

现在,我预计 sub_41104B 将直接导致 printf,但事实并非如此:

sub_41104B proc near
jmp     sub_411870
sub_41104B endp

最后,在 sub_411870 中,printf 函数启动。有人可以解释为什么编译器不直接使用 call sub_411870 吗?

最佳答案

Now, I expect sub_41104B will lead directly to printf ...

... 或直接到 puts()

... but thats not the case

你反汇编的是目标文件还是最终的 EXE 文件?

如果你反汇编了EXE文件,你调用的函数很可能在LIB文件中实现为函数“重命名”另一个:

int puts(const char *text) // this is sub_41104B
{
    return __x_puts(text); // __x_puts is sub_411870
}

在 DLL 文件中调用函数时,您经常会看到这种情况。但是,对于 DLL 文件,jmp 指令是间接跳转 (jmp dword ptr [411870]),而不是直接跳转。

关于c - 为什么我的编译器(VS2017)选择 'CALL-JMP' 来到达子例程而不是仅仅 'CALL' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55626006/

相关文章:

c# - 在 Visual Studio 中创建转换器的最快方法

assembly - 为什么在汇编程序中使用系统调用?

c++ - C/C++中的gettext国际化系统的性能开销

c - 数据类型在计算机中究竟是如何表示的?

c - 漂亮的树打印屏幕限制

visual-studio - 如何更改 Visual Studio 代码设置

c - gcc 对初始化程序中大括号的提示(嵌套结构)

visual-studio - Umbraco Backoffice 没有注册对自定义属性编辑器所做的更改

c - gcc 输出反汇编中的 data32 data32 nopw %cs :0x0(%rax, %rax,1) 指令的含义是什么?

gcc - 为什么空函数不只是返回