汇编语言和本地代码及通过编译器输出汇编语言的源代码

时间:2022-10-08 19:00:15


目录

​一、汇编语言和本地代码​

​二、通过编译器输出汇编语言的源代码​


一、汇编语言和本地代码

        计算机CPU只能运行本地代码(机器语言)程序,用C语言等高级语言编写的代码,需要经过编译器编译后,转换为本地代码才能够被CPU解释执行

        但是本地代码的可读性非常差,所以需要使用一种能够直接读懂的语言来替换本地代码,那就是在各本地代码中,附带上表示其功能的英文缩写,比如在加法运算的本地代码加上 add(addition)的缩写、在比较运算符的本地代码中加上 cmp(compare)的缩写等,这些通过缩写来表示具体本地代码指令的标志称为 助记符,使用助记符的语言称为 汇编语言。这样,通过阅读汇编语言,也能够了解本地代码的含义了

        不过,即使是使用汇编语言编写的源代码,最终也必须要转换为本地代码才能够运行,负责做这项工作的程序称为 编译器,转换的这个过程称为 汇编。在将源代码转换为本地代码这个功能方面,汇编器和编译器是同样的

        用汇编语言编写的源代码和本地代码是一一对应的。因而,本地代码也可以反过来转换成汇编语言编写的代码。把本地代码转换为汇编代码的这一过程称为 反汇编,执行反汇编的程序称为 反汇编程序

本地代码和汇编语言一对一的转换:

汇编语言和本地代码及通过编译器输出汇编语言的源代码

        哪怕是C语言编写的源代码,编译后也会转换成特定的CPU用的本地代码。而将其反汇编的话,就可以得到汇编语言的源代码,并对其内容进行调查。不过,本地代码变成C语言源代码的反编译,要比本地代码转换成汇编代码的反汇编要困难,这是因为,C语言代码和本地代码不是一一对应的关系

二、通过编译器输出汇编语言的源代码

本地代码可以经过反汇编转换成为汇编代码,但是只有这一种转换方式吗?显然不是,C语言编写的源代码也能够通过编译器编译称为汇编代码,下面可以进行尝试一下

首先需要先做一些准备,需要先下载 Borland C++5. 5 编译器,为了方便,我这边直接下载好了读者直接从我的百度网盘提取即可(链接:​https://pan.baidu.com/s/19LqVICpn5GcV88thD2AnIA​密码:hz1u)

下载完毕,需要进行配置,下面是配置说明(​https://wenku.baidu.com/view/22e2f418650e52ea551898ad.html​),教程很完整跟着配置就可以,下面开始我们的编译过程

首先用 Windows 记事本等文本编辑器编写如下代码

// 返回两个参数之和的函数
int AddNum(int a,int b){
return a + b;
}

// 调用AddNum 函数的函数
void MyFunc(){
int c;
c = AddNum(123,456);
}

        编写完成后将其文件名保存为Sample4.c,C语言源文件的扩展名,通常用.c来表示,上面程序是提供两个输入参数并返回它们之和。

        在Windows 操作系统下打开 命令提示符,切换到保存Sample4.c的文件夹下,然后在命令提示符中输入

bcc32-c-S Sample4.c

        bcc32 是启动 Borland C++的命令,-c 的选项是指仅进行编译而不进行链接,-S选项被用来指定生成汇编语言的源代码

        作为编译的结果,当前目录下会生成一个名为 Sample4.asm 的汇编语言源代码。汇编语言源文件的扩展名,通常用.asm来表示,下面就让我们用编辑器打开看一下 Sample4.asm中的内容:

.386p
ifdef ??verdion
if ??version GT 500H
.mmx
endif
endif
model flat
ifndef ??version
?debug macro
endm
endif
?debug S "Sample4.c"
?debug T "Sample4.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
?livel1@0:
;
; int AddNum(int a,int b){
;
push ebp
mov ebp,esp
;
;
; return a + b;
;
@1:
mov eax,dword ptr [ebp+8]
add eax,dword ptr [ebp+12]
;
; ;
;
@3:
@2:
pop ebp
ret
_AddNum endp
_MyFunc proc near
?livel@48:
;
; void MyFunc(){
;
push ebp
mov ebp,esp
;
; int c;
; c = AddNum(123,456);
;
@4:
push 456
push 123
call _AddNum
add esp,8
;
; }
;
@5:
pop dep
ret
_MyFunc endp
_TEXT ends
public _AddNum
public _MyFunc
?debug D "Sample4.c" 20343 45835
end

这样编译器就能成功把C语言转换成汇编代码了