目录
写在开头
本文继续阅读总结《程序是怎样跑起来的》这本书(作者:矢泽久雄),也是关于这本书的最后一篇读书笔记。前三篇博客介绍了这本书的阅读感受,并分别对第一章CPU、第四章内存相关、第五章磁盘、第八章程序的知识进行了总结。详情见:
【计算机组成原理】读书笔记第一期:对程序员来说CPU是什么-优快云博客
【计算机组成原理】读书笔记第二期:使用有棱有角的内存_Bossfrank的博客-优快云博客
【计算机组成原理】读书笔记第三期:内存和磁盘的关系-优快云博客
【计算机组成原理】读书笔记第四期:从源文件到可执行文件_Bossfrank的博客-优快云博客

本篇博客将介绍本书的第十章:通过汇编语言了解程序的实际构成,将从汇编语言和本地代码的关系、汇编语言的源代码(伪指令、栈的机制、函数的调用机制、局部变量/全局变量、程序的流程控制等)两个角度进行介绍。本章是非常重点硬核的内容,了解汇编语言,是了解程序运行过程中各寄存器的存储情况、程序的执行顺序、函数的调用栈等知识的基础。了解底层的汇编语言,也对我们学习编写、调试高级程序语言大有裨益。
汇编语言和本地代码的关系
一言以蔽之,汇编语言和本地代码是一一对应的。本节内容较少,重点读者能回答以下几个问题就算知道重点了。
汇编语言存在的意义是什么?
用来直观的展现本地代码。CPU只能执行本地代码,通过调查本地代码的内容,可以了解程序最终是以何种形式来运行的。但是,如果直接打开本地代码来看的话,只能看到二进制数值的罗列。因而通过在各本地代码中,附带上表示其功能的英语单词缩写(助记符),就可以表示本地代码了,这样就有助于程序员了解程序的本质了。
汇编语言能直接运行吗?
不能!即使是用汇编语言编写的源代码,最终也必须要转换成本地代码才能运行。负责转换工作的程序称为汇编器,转换这一处理本身称为汇编。 不过用汇编语言编写的.asm源代码,和本地代码是一一对应的。因而,本地代码也可以反过来转换成汇编语言的源代码。持有该功能的逆变换程序称为反汇编程序,逆变换这一处理本身称为反汇编。

C语言等高级程序语言与本地代码是啥关系?与汇编语言又是啥关系?
C语言等高级语言最后必须转换为本地代码才能被CPU执行,但要注意,像C语言这样的高级程序设计语言与本地代码不是一一对应的,因此和汇编语言也不是一一对应的,因此反编译会比较困难(从汇编语言转换回C语言)。不过大部分C语言编译器,都可以把利用C语言编写的源代码转换成汇编语言的源代码。
汇编语言的源代码
本节内容比较多,通过代码举例说明。假设有如下C语言编写的的sample.c源代码 :
//代码10-1 C语言实例源代码sample.c
// 返回两个参数值之和的函数
int AddNum(int a, int b)
{
return a + b;
}
// 调用AddNum 函数的函数
void MyFunc()
{
int c;
c = AddNum(123, 456);
}
这个C语言片段言简意赅,接下来的小节将通过对这段C语言代码的汇编代码进行说明。注意由于没有main函数,这段代码是没办法运行的,仅仅是学习汇编需要。通过使用编译器的汇编功能,生成对应汇编代码sample.asm如下:
;代码10-2,源代码sample.c转换的汇编代码sample.asm
_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
可以发现,C 语言的源代码和转换成汇编语言的源代码是交叉显示的。而这也为我们对两者进行比较学习提供了绝好的教材。在该汇编语言代码中,分号(;)以后是注释。由于C语言的源代码变成了注释,因此就可以直接对Sample.asm 进行汇编并将其转换成本地代码了 。刚刚看到汇编语言的源代码可能感觉一头雾水,莫慌,下面我们将逐一进行讲解。
伪指令
汇编语言的源代码,是由转换成本地代码的指令(后面讲述的操作码)和针对汇编器的伪指令构成的。伪指令负责把程序的构造及汇编的方法指示给汇编器(转换程序)。不过伪指令本身是无法汇编转换成本地代码的。也就是说,伪指令没有对应的本地代码。把代码10-2 中用到的伪指令部分摘出,如代码10-3 所示。
_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
_AddNum endp
_MyFunc proc near
_MyFunc endp
_TEXT ends
end
由伪指令segment 和ends围起来的部分,是给构成程序的命令和数据的集合体加上一个名字而得到的,称为段定义。在程序中,段定义指的是命令和数据等程序的集合体的意思。一个程序由多个段定义构成。

本文是《程序是怎样跑起来的》的读书笔记,介绍汇编语言与本地代码关系,指出汇编可直观展现本地代码但需转换才能运行。还阐述汇编源代码、伪指令、基本语法、常见指令,如mov、push和pop等,以及程序流程控制,包括循环和条件分支,强调了解汇编对理解程序运行的重要性。
最低0.47元/天 解锁文章
731

被折叠的 条评论
为什么被折叠?



