【计算机组成原理】读书笔记第五期:通过汇编语言了解程序的实际构成

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

目录

写在开头

汇编语言和本地代码的关系

汇编语言的源代码 

伪指令

汇编的基本语法

常见的汇编指令

mov

push和pop

函数的使用机制

函数的调用

函数参数的传递与返回值

全局变量

局部变量

程序的流程控制

循环语句

条件分支

通过汇编语言了解程序运行方式的必要性

结尾

写在开头

  本文继续阅读总结《程序是怎样跑起来的》这本书(作者:矢泽久雄),也是关于这本书的最后一篇读书笔记。前三篇博客介绍了这本书的阅读感受,并分别对第一章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围起来的部分,是给构成程序的命令和数据的集合体加上一个名字而得到的,称为段定义。在程序中,段定义指的是命令和数据等程序的集合体的意思。一个程序由多个段定义构成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Boss_frank

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值