编程语言
首页 > 编程语言> > 汇编 第四章 第一个汇编程序

汇编 第四章 第一个汇编程序

作者:互联网

第四章 第一个汇编程序

4.1 一个源程序从写出到执行的过程
编写汇编源程序

用文本编辑器(如记事本Nodepad++、UltraEdit等),用汇编语言编写汇编源程序。宏汇编程序(MASM)macroassembler:具有宏加工功能的汇编程序

​ 1.一个汇编语言程序从写出到最终执行的简要过程
​ 编写->编译连接->执行
​ 2.对源程序进行编译连接
​ 1.使用汇编语言编译程序(MASM.EXE)对源程序文件中的源程序进行编译,产生目标文件【.obj文件】
​ 2.再用连接程序(LINK.EXE)对目标文件进行连接,生成可在操作系统中直接运行的可执行文件【.EXE文件】。
​ 3.可执行文件包含两部分内容
​ 1.程序(从源程序的汇编指令翻译过来的机器码)和数据(源程序中定义的数据)
​ 2.相关的描述信息(比如:程序有多大、要占多少内存空间等)
​ 4.执行可执行文件中的程序
​ 1.在操作系统(如:MSDOS)中,执行可执行文件中的程序
​ 2.操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存
​ 并进行相关的初始化(比如:设置CS:IP指向第一条要执行的指令),然后由CPU执行程序

4.2 源程序的主要结构

​ 源程序由 汇编指令+伪指令+宏指令 组成
​ 伪指令:编译器处理
​ 汇编指令:编译为机器码

假设 assume :cs寄存器 (code segment)名字为codesg

1.伪指令
​ 1.没有对应的机器码的指令,不能由CPU直接执行
​ 2.伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作
2. segmentends【定义一个段】

  1. segment和ends是一对成对使用的伪指令
  2. 编写汇编程序【必须】使用到的指令
  3. segment和ends的功能是定义一个段
    segment:说明一个段开始
    ends:说明一个段结束
  4. 一个段必须有一个名称来标识,使用格式为
    段名 segment
    段名 ends
  5. 一个汇编程序由多个段组成
    这些段用来存放【代码、数据、或当作栈空间】来使用
    一个有意义的汇编程序至少要有一个段,这个段用来存放代码。

3.end【真正的没了】

  1. end是一个汇编程序的结束标记
  2. 编译器在编译汇编程序的过程中,如果碰到了伪指令end,就结束对源程序的编译
  3. 如果程序写完了,要在结尾处加上伪指令end
    否则,编译器无法知道程序在何处结束
    【切记】不要把end和ends搞混了
    end:汇编程序的结束标记
    ends:与segment成对出现

4.assume【寄存器和段的关联假设】
1.它假设某一段寄存器和程序中的某一个用segment…ends定义的段相关联
2.通过assume说明这种关联,在需要的情况下,
编译程序可以将段寄存器和某一具体的段相联系
5.程序和源程序
1.我们将源程序文件中的所有内容称为【源程序】
2.将源程序中最终由计算机执行处理的指令或数据称为【程序】
3.程序最先以汇编指令的形式,存储在源程序
然后经过编译、连接后转变为机器码,存储在可执行文件中
在这里插入图片描述6. 标号,标号与段名称有所区别
1.一个标号codesg指代了一个地址,即是段名称。
2.段名称 放在segment的前面,作为一个段的名称
这个段的名称最终将被汇编、连接程序处理为一个段的段地址
7. DOS中的程序运行

  1. DOS是一个单任务操作系统
  2. 一个程序结束后,将CPU的控制权交还给是他得以运行的程序,我们称这个过程为:程序返回ret

8.程序返回
mov ax,4c00H
int(interrupt) 21H ;【中断机制】是DOS最伟大的机制,Windows系统上是【消息机制】
这两条指令所实现的功能就是程序返回
9.几个和结束相关的内容
1.段结束:伪指令
通知编译器一个段的结束【ends】
2.程序结束:伪指令
通知编译器程序的结束【end】
3.程序返回:汇编指令
mov ax,4c00H
int 21H
在这里插入图片描述10.语法错误和逻辑错误
1.语法错误
1.程序在编译时被编译器发现的错误
2.容易发现
2.逻辑错误
1.在编写时不会表现出来的错误、在运行时会发生的错误
2.不容易发现

4.3 编辑源程序

之前dosbox debug 程序按quit退出后继续进入有masm的目录进入edit,要有这个程序才能使用。

编辑好内容后按alt选中save as 输入名字test.asm后enter保存
在这里插入图片描述

按alt键后出现光标上下左右切换 即可exit 选中后enter,最后在文件夹出现了。
在这里插入图片描述

4.4 编译

运行masm后会出现版本信息。输入要编译的源文件名字。会生成obj文件,按enter即可。后面两个目标文件可以忽略,也是按enter。
在这里插入图片描述

注意,在编译的过程中,我们提供了一个输入,即源程序文件。最多可以得到3个输出:目标文件(.obj)、列表文件(.Ilst)、交叉引用文件(.crf),这3个输出文件中,目标文件是我们最终要得到的结果,而另外两个只是中间结果,可以让编译器忽略对它们的生成。在汇编课程中,我们不讨论这两类文件。

4.5 连接

输入link后再输入obj文件名按enter 生成exe文件,剩下的enter忽略

在这里插入图片描述

汇编和连接的作用

​ 1.当源程序很大时,可以将他们分成多个源程序文件夹编译,每个源程序编译成为目标文件后,再用连接程序将它们连接在一起,生成一个可执行文件。
​ 2.程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件
​ 3.一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。
​ 所以在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件

最终生成的文件
在这里插入图片描述

我们用汇编语言编程,就要用到:编辑器(Edit)、编译器( masm)、连接器( link )、调试工具( debug)等所有工具,他们都是在操作系统之上运行的程序,所以我们的学习过程必须在操作系统的环境中进行。

4.6 以简化方式进行编译和连接

masm test; link test;

在这里插入图片描述

​ 汇编使用的程序:masm.exe test.asm; 生成test.obj
​ 连接使用的程序:link.exe test.obj; 生成test.exe
​ 简化方式进行汇编和连接的程序:ml.exe test.asm(ml 两个同时生成了,上面不加分号; 需要一步步确定)

4.7 exe的执行

在这里插入图片描述

奇怪吗?程序运行后,竟然没有任何结果,就和没有运行一样。那么,程序到底运行了吗?
程序当然是运行了,只是从屏幕上不可能看到任何运行结果,因为,我们的程序根本没有向显示器输出任何信息。程序只是做了一些将数据送入寄存器和加法的操作,而这些事情,我们不可能从显示屏上看出来。程序执行完成后,返回,屏幕上再次出现操作系统的提示符

4.8 可执行文件中的程序装入内存并运行的原理

​ 1.在DOS中,可执行文件中的程序P1若要运行,必须有一个正在运行的程序P2,将P1从可执行文件中加载入内存,将CPU的控制权交给P1,P1才能得以运行
​ 2.当P1运行完毕后,应该将CPU的控制权交还给使他得以运行的程序P2
​ 3.操作系统的外壳
​ 1.操作系统是由多个功能模块组成的庞大、复杂的软件系统
​ 任何通用的操作系统,都需要提供一个称为shell(外壳)的程序,
​ 用户(操作人员)使用这个程序来操作计算机系统工作
​ 2. DOS中有一个程序command.com,这个程序在DOS中称为命令解释器,也就是DOS系统的shell
在这里插入图片描述

用debug加载程序,可以看到,Debug 将程序从可执行文件加载入内存后,cx 中存放的是程序的长度。1.exe中程序的机器码共有15个字节。则1.exe加载后,cx 中的内容为000FH。
在这里插入图片描述

可以看到,ds是075a,从076a:0000~076a:000E都是程序的机器码。cs和ds相差了10H。这256个字节存放psp。
在这里插入图片描述

(1)程序加载后,ds中存放着程序所在内存区的段地址,这个内存区的偏移地址为0,则程序所在的内存区的地址为ds:0;
(2)这个内存区的前256个字节中存放的是PSP,DOS用来和程序进行通信。从256字节处向后的空间存放的是程序。
所以,从 ds 中可以得到PSP的段地址SA,PSP的偏移地址为0,则物理地址为SA×16+0。
因为PSP占256(100H)字节,所以程序的物理地址是:SA×16+0+256= SA×16+16×16+0=(SA+16)×16+0可用段地址和偏移地址表示为: SA+10H:0。

现在,我们可以开始跟踪了,用T命令单步执行程序中的每一条指令,并观察每条指令的执行结果,到了int 21,我们要用Р命令执行
在这里插入图片描述

使用Q命令退出 Debug,将返回到command 中,因为Debug 是由 command 加载运行的。在 DOS中用“debug 1.exe”运行 Debug对1.exe进行跟踪时,程序加载的顺序是:command 加载Debug,Debug加载1.exe。返回的顺序是:从 1.exe中的程序返回到Debug,从 Debug返回到command

4.执行可执行文件1.exe时,
​ (1)什么程序将CPU的控制权交给了1.exe?
​ (2)将程序1.exe加载入内存后,如何使程序得以运行?
​ (3)1.exe程序运行结束后,返回到了哪里?
​ 1.在DOS中直接执行1.exe时,是正在运行的cmd.exe将1.exe中的程序加载入内存
​ 2. cmd.exe设置CPU的CS:IP指向程序的第一条指令(即,程序的入口)
​ 从而使程序得以运行
​ 3.程序运行结束后,返回cmd.exe中,CPU继续运行cmd.exe

【实验三】编程、编译、连接、跟踪

assume cs:codesg
codesg segment
	mov ax,2000H
	mov ss,ax
	mov sp,0
	add sp,10
	pop ax
	pop bx
	push ax
	push bx
	pop ax
	pop bx
	mov ax,4c00H
	int 21H
codesg ends
end

在这里插入图片描述

PSP的头两个字节是CD 20,用 Debug加载t1.exe,查看PSP的内容。用-u查看是int 20

在这里插入图片描述

标签:可执行文件,汇编,exe,文件,程序,汇编程序,编译,源程序,第四章
来源: https://blog.csdn.net/soulweee/article/details/115612007