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

发布于:2022-11-30 ⋅ 阅读:(855) ⋅ 点赞:(0)

目录

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

二、汇编语言的语法


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

        汇编代码看起来比较难,不过实际上其实比较简单,而且可能比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的种类决定的,下面对操作码的功能进行了整理。

部分操作码及其功能:

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

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

CPU和内存的关系:

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

x86系列CPU的主要寄存器:

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

网站公告

今日签到

点亮在社区的每一天
去签到