Win知识 - 程序是怎样跑起来的——通过编译器输出汇编语言的源代码

简介: Win知识 - 程序是怎样跑起来的——通过编译器输出汇编语言的源代码

除了将本地代码进行反汇编这一方法外,通过其他方式也可以获取汇编语言的源代码。大部分C语言编译器,都可以把利用C语言编写的源代码转换成汇编语言的源代码,而不是本地代码。利用该功能,就可以对C语言的源代码和汇编语言的源代码进行比较研究。笔者在学生时代的报告中,使用的便是该功能。Borland C++中,通过在编译器的选项中指定“-S”,就可以生成汇编语言的源代码了。大家也可以实际尝试一下。

用Windows的记事本等文本编辑器编写如代码清单10-1所示的C语言源代码,并将其命名为Sample4.c进行保存。C语言源文件的扩展名,通常用“.c”来表示。该程序是由返回参数的两个整数值之和的AddNum函数①和调用AddNum函数的MyFunc函数构成的。因为没有包含程序运行起始位置②的main函数部分,这种情况下直接编译是无法运行的。大家只需把它看成是学习汇编语言的一个示例即可。

代码清单10-1 由两个函数构成的C语言的源代码

    //返回两个参数值之和的函数
    int AddNum(int a, int b)
    {
        return a + b;
    }
    //调用AddNum函数的函数
    void MyFunc()
    {
        int c;
        c =AddNum(123, 456);
    }

由Windows开始菜单启动命令提示符,把当前目录③变更到Sample4.c保存的文件夹后,输入下面的命令并按下Enter键。bcc32是启动Borland C++编译器的命令。“-c”选项指的是,仅进行编译而不进行链接④。“-S”选项被用来指定生成汇编语言的源代码。

bcc32 -c -S Sample4.c

作为编译的结果,当前目录下会生成一个名为Sample4.asm的汇编语言源代码。汇编语言源文件的扩展名,通常用“.asm”来表示。下面就让我们使用记事本来看一下Sample4.asm的内容。可以发现,C语言的源代码和转换成汇编语言的源代码是交叉显示的。而这也为我们对两者进行比较学习提供了绝好的教材。在该汇编语言代码中,分号(; )以后是注释。由于C语言的源代码变成了注释,因此就可以直接对Sample4.asm进行汇编并将其转换成本地代码了(代码清单10-2)。


代码清单10-2 编译器生成的汇编语言源代码(一部分做了省略,彩色部分是转换成注释的C语言源代码)

    _TEXT  segment dword public use32 'CODE'
    _TEXT  ends
    _DATA  segment dword public use32 'DATA'
    _DATA  ends
    _BSS   segment dword public use32 'BSS'
    _BSS   ends
    DGROUP group    _BSS, _DATA
    _TEXT  segment dword public use32 'CODE'
    _AddNum         proc     near
        ;
        ;   int AddNum(int a, int b)
        ;
            push       ebp
            mov        ebp, esp
        ;
        ;   {
        ;        return a + b;
        ;
            mov        eax, dword ptr [ebp+8]
            add        eax, dword ptr [ebp+12]
        ;
        ;   }
        ;
            pop        ebp
            ret
    _AddNum         endp
    _MyFunc         proc     near
        ;
        ;   void MyFunc()
        ;
            push       ebp
            mov        ebp, esp
        ;
        ;  {
        ;        int c;
        ;        c =AddNum(123, 456);
        ;
            push       456
            push       123
            call       _AddNum
            add        esp,8
        ;
        ;   }
        ;
            pop        ebp
            ret
    _MyFunc         endp
    _TEXT  ends
            end

Ps:注脚

①AddNum函数仅仅返回两个参数值的相加结果。在实际的编程中,这种函数是不需要的。为了说明函数调用的机制,这里特意使用了这种简单的函数。


②在命令提示符上运行的程序中,main函数位于程序运行起始位置。而在Windows上运行的程序中,WinMain函数位于程序运行起始位置。程序运行起始位置也称为“入口点”。


③当前目录指的是当前正在打开的目录(文件夹)。在命令提示符下对C语言的源文件进行编译时,该文件所在的目录必须是当前目录,所以有时候就需要变换当前目录。变换当前目录时,只需在命令提示符中的“CD”后面空上一个半角空格,然后加上需要跳转的目录,再按下回车即可。例如,如果要将\Test指定为当前目录的话,只需输入 CD \Test然后按下回车键即可。CD是Change Directory的略称。


④链接是指把多个目标文件结合成1个可执行文件。详情请参考第8章。


目录
相关文章
|
12月前
|
编译器 C语言 数据安全/隐私保护
汇编语言和本地代码及通过编译器输出汇编语言的源代码
汇编语言和本地代码及通过编译器输出汇编语言的源代码
81 0
|
12月前
|
存储 Java C++
汇编语言、寄存器分类及程序计数器
汇编语言、寄存器分类及程序计数器
90 0
|
12月前
|
C语言
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(三)
|
12月前
|
编译器 C语言
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(二)
|
12月前
|
存储 自然语言处理 程序员
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(一)
进阶C语言 第七章-------《程序的编译(预处理操作)+链接》 (预编译、编译、汇编、#define、条件编译,#include的包含)知识点+完整思维导图+基本练习题+深入细节+通俗易懂建议收藏(一)
|
Linux 编译器 C语言
『Linux从入门到精通』第 ⑦ 期 - Linux编译器——gcc/g++(预处理、编译、汇编、链接)
『Linux从入门到精通』第 ⑦ 期 - Linux编译器——gcc/g++(预处理、编译、汇编、链接)
90 0
|
存储 API C语言
从反汇编看恶意程序的C语言结构(二)
从反汇编看恶意程序的C语言结构
94 0
|
编译器 API 分布式数据库
从反汇编看恶意程序的C语言结构(一)
从反汇编看恶意程序的C语言结构
111 0
|
存储 程序员
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
92 0
Win知识 - 程序是怎样跑起来的——汇编语言的语法是“操作码+操作数”
|
编译器 C语言
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的
112 0
Win知识 - 程序是怎样跑起来的——汇编语言和本地代码是一一对应的