不会转换成本地代码的伪指令及汇编语言的语法

目录

一、不会转换成本地代码的伪指令

二、汇编语言的语法


一、不会转换成本地代码的伪指令

        汇编代码看起来比较难,不过实际上其实比较简单,而且可能比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

_AddNum proc near
_AddNum endp

_MyFunc proc near
_MyFunc endp

_TEXT ends
end

        由伪指令segmentends 围起来的部分,是给构成程序的命令和数据的集合体上加一个名字而得到的,称为 段定义。段定义的英文表达具有 区域的意思,在这个程序中,段定义指的是命令和数据等程序的集合体的意思,一个程序由多个段定义构成

        上面代码的开始位置,定义了3个名称分别为_TEXT、_DATA、_BSS 的段定义,_TEXT 是指定的段定义,_​​​​​​​DATA 是被初始化(有初始值)的数据的段定义,_BSS 是尚未初始化的数据的段定义。这种定义的名称是由Borland C++定义的,是由 Borland C++编译器自动分配的,所以程序段定义的顺序就成为了_TEXT、_DATA、_BSS,这样也确保了内存的连续性

_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use 'DATA'
_DATA ends
_BSS segment dword public use32 'BSS'
_BSS ends

        段定义(segment)是用来区分或者划分范围区域的意思。汇编语言的segment伪指令表示段定义的起始,ends 伪指令表示段定义的结束。段定义是一段连续的内存空间

group 这个伪指令表示的是将_BSS和_DATA 这两个段定义汇总名为 DGROUP 的组

DGROUP group_BSS, _DATA

        围起_AddNum_MyFun_TEXT segment 和_TEXT ends,表示_AddNum_MyFun属于_TEXT 这一段定义的

_TEXT segment dword public use32 'CODE'
_TEXT ends

        因此,即使在源代码中指令和数据是混杂编写的,经过编译和汇编后,也会转换成为规整的本地代码

        _AddNum proc_AddNum endp 围起来的部分,以及 _MyFuncproc_MyFunc endp 围起来的部分,分别表示AddNum函数和MyFunc函数的范围

_AddNum proc near
_AddNum endp

_MyFunc proc near
_MyFunc endp

        编译后在函数名前附带上下划线 _ ,是Borland C++ 的规定。在C语言中编写的AddNum函数,在内部是以 _AddNum 这个名称处理的。伪指令 proc 和 endp 围起来的部分,表示的是过程(procedure)的范围。在汇编语言中,这种相当于C语言的函数形式称为过程。末尾的end伪指令,表示的是源代码的结束

二、汇编语言的语法

        在汇编语言中,一行表示一对CPU的一个指令。汇编语言指令的语法结构是操作码+操作数,也存在只有操作码没有操作数的指令。

        操作码表示的是指令动作,操作数表示的是指令对象。操作码和操作数一起使用就是一个英文指令。比如从英语语法来分析的话,操作码是动词,操作数是宾语。比如这个句子 Give me money 这个英文指令的话,Give 就是操作码,me和money就是操作数。汇编语言中存在多个操作数的情况,要用逗号把它们分割,就像是 Give me,money 这样

能够使用何种形式的操作码,是由CPU的种类决定的,下面对操作码的功能进行了整理。

部分操作码及其功能:

操作码操作数功能数
movA,B把B的值赋给A
andA,B把A和B同时相加,并把结果赋给A
pushA把A的值存储在栈中
popA从栈中读出值,并将其赋值给A
callA调用函数A
ret处理返回给调用源函数

本地代码需要加载到内存后才能运行,内存中存储着构成本地代码的指令和数据。程序运行时,CPU会从内存中把数据和指令读出来,然后放在CPU内部的寄存器进行处理

CPU和内存的关系:

23848fe8f3dc4914b9fcbe945e7253b5.png

 寄存器是CPU中的存储区域,寄存器除了有临时存储和计算的功能之外,还具有运算功能,x86系列的主要种类和角色如下图所示

x86系列CPU的主要寄存器:

寄存器名名称主要功能
eax累加寄存器运算
ebc基址寄存器存储内存地址
ecx计数寄存器计算循环次数
edx数据寄存器存储数据
esi源基址寄存器存储数据发送源的内存地址
edi目的基址寄存器存储数据发送目标的内存地址
ebp扩展基址指针寄存器存储数据存储领域基点的内存地址
esp扩展栈指针寄存器存储栈中最高位数据的内存地址

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夏志121

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

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

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

打赏作者

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

抵扣说明:

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

余额充值