X86汇编6.编写汇编语言程序

李辉 2020-02-26

最近学习了X86汇编,其实无论是古老的8086还是现在i3/5/7/9,Xeon3/5,在最基本原理上,都是相通的,只是CPU位数,寻址空间,寄存器个数,指令集的扩充等方面有所不同,对于学习,8086永不过时。

1.程序从写入到执行的过程
(1)编写汇编程序代码===>输出程序文件,helloworld.asm 或 helloword.s(一般linux下用.S命名汇编文件)
(2)对代程序代码进行编译和链接
编译就是: 源码文件---编译--->目标文件
链接就是: 目标文件---链接--->可执行程序
可执行程序包含两部分:(1)代码(汇编指令翻译过来的机器码)和数据(程序中定义的数据),前面说过,无论是代码还是数据,都是二进制的(2)相关的描述信息,如:程序多大,占用多少内存空间,哪里是代码,哪里是数据
(3)执行可执行程序,操作系统依照可执行程序文件中的描述信息,将可执行程序的机器码和数据加载如内存,并进行初始化(如:CS:IP指向第一条要执行的指令),然后CPU开始执行程序。

2.程序
汇编指令:有对应机器码的指令,可以被编译为机器指令
伪指令:不被CPU执行,没有对应的机器指令,是由编译器来执行的指令,编译器根据伪指令来进行相关的编译操作。
示例:
assume cs:codesg
codesg segment
mov ax, 0123H
mov bx, 0456H
add ax, bx
mov ax,4c00H
int 21H
codesg ends
end
(1)伪指令segment...ends
格式:
XXX segment ;定义一个一个段开始,名称为XXX
XXX ends ;定义一个段结尾,名称为XXX
释义:segment...ends指令对,定义一个段XXX。
(2)end
end是一个汇编程序结束的标志。
(3)assume
表示假设,它假设某一段寄存器和程序中的某一个sgment...ends定义的段相关联,上面示例assume cs:codesg就是将代码段codesg和CPU中的段寄存器cs联系起来。

标号:代表一个地址,最终被链接器处理为一个段的段地址
程序结构:段、汇编指令,段和cs关联,程序返回,程序结束标志

编译(linux环境): nasm -felf64 hello.asm
链接(linux环境): ld -o hello hello.o

3.程序运行环境
在dos环境下,CPU是实时模式运行的,我们的汇编代码可以写入任何地址。
在非dos环境下,如:windows 2000/xp/7/8/10下,CPU是保护模式运行,即使是汇编代码也不允许访问一些严格保护的内存单元。

4.模块化程序设计
call与ret共同支持了汇编语言的模块化设计,也就是函数。用寄存器来存储参数和结果是最常使用的方法。对于存放参数的寄存器和存放结果的寄存器,调用者和子程序的读写操作恰恰相反:调用者将参数送入参数寄存器,从结果寄存器中取到返回值,子程序从参数寄存器中取到参数,将返回值送入结果寄存器。
多个参数的传递:将参数存入一段内存地址,然后将段地址传到寄存器,传给程序。类似于C语言传指针,但本质是用栈存参数。

相关推荐