《汇编源程序与上机过程.ppt》由会员分享,可在线阅读,更多相关《汇编源程序与上机过程.ppt(44页珍藏版)》请在三一办公上搜索。
1、实验二 第一个汇编语言源程序,汇编语言源程序,用汇编语言编写的程序称为汇编源程序。汇编语言源程序比机器语言程序容易理解和掌握,也容易调试和维护。但是,计算机能读懂的只有机器指令,必须使用编译器将汇编语言源程序翻译成机器语言程序才可以由计算机执行。这个翻译的过程称为“汇编”,目前,常用的汇编程序(编译器)有:MASM、TASM和DEBUG等。本教材采用的是MASM 5.0宏汇编。用汇编语言编写程序的工作过程,MASM 5.0,我们用汇编语言编程,要用到:编辑器(Edit)、编译器(masm)、连接器(link)、调试工具(debug)等所有工具,而这些工具都是在操作系统之上运行的程序,所以我们的
2、学习过程必须在操作系统的环境中进行。,1、编辑源程序打开记事本或进入DOS方式,运行Edit,在其中编辑程序,保存文件(*.asm)。如下图所示:,2、编译,进入DOS方式,进入 C:masm 目录,运行masm.exe。在输入源程序文件名的时候一定要指明它所在的路径。如果文件就在当前路径下,只输入文件名就可以。然后一路回车,产生的目标文件名(.obj)默认与源文件名一致.编译结束,编译器输出的最后两行告诉我们这个源程序有没有警告错误和必须要改正的致命错误。,以简化的方式进行编译,编译:,3、连接,在对源程序(*.asm)进行编译得到目标文件(*.obj)后,我们需要对目标文件进行连接,从而得
3、到可执行文件(*.exe)。连接程序默认要输出的可执行文件名为 1.EXE,所以不必再另行指定文件名。我们直接按 Enter 键。,以简化的方式进行连接,连接:,连接的作用有以下几个:当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行文件;程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件;一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。所以,在只有一个源程序文件,而又不需要调用某
4、个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件。,4、执行,现在,终于将我们的第一个汇编程序加工成了一个可在操作系统下执行的程序文件。1.exe的执行情况:程序到底运行没有?程序当然运行了,只是从屏幕上不可能看到任何运行结果。我们的程序没有像显示器输出任何信息。程序只是做了一些将数据送入寄存器和加法的操作,而这些事情,我们不可能从显示屏上看出来。程序执行完成后返回,屏幕上再次出现操作系统的提示符。,5、使用DEBUG调试和运行可执行文件,在初次使用DEBUG时,可参照下列步骤进行:1、调用DEBUG,装入用户程序2、U命令反汇编程序,记录代码段与数据段首地址3、R观
5、察寄存器初始状态 4、以单步工作方式T开始运行程序 5、D观察用户程序数据段初始内容6、继续以单步工作方式运行程序 7G连续工作方式运行程序 8E或A修改程序和数据 9运用断点调试程序 G,6、源程序,汇编指令:有对应的机器码,可被机器执行的指令。伪指令:没有对应机器码,有编译器执行的指令。XXX segment XXX ends end assume,定义一个段,segment和ends是一对成对使用的伪指令,这是在写可被编译器编译的汇编程序时,必须要用到的一对伪指令。功能:定义一个段,segment说明一个段开始,ends 说明一个段结束。一个段必须有一个名称来标识,使用格式为:段名 se
6、gment 段名 ends一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间来使用。一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。(汇编语言源程序至少要有一个代码段),程序结束标记,End 是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令 end,就结束对源程序的编译。如果程序写完了,要在结尾处加上伪指令end。否则,编译器在编译程序时,无法知道程序在何处结束。注意:不要搞混了end和ends。,通知编译器程序结束,通知编译器一个段结束,寄存器与段的关联假设,assume:含义为“假设”。它假设某一段寄存器和程序中的某一个用 segment
7、 ends 定义的段相关联。通过assume说明这种关联,在需要的情况下,编译程序可以将段寄存器和某一个具体的段相联系。格式 段寄存器:段名,标号,一个标号指代了一个地址。codesg:放在segment的前面,作为一个段的名称,这个段的名称最终将被编译、连接程序处理为一个段的段地址。start:放在程序的开始,是程序的入口,编译时被处理为该条指令的偏移地址。,程序返回,这两条指令所实现的功能是程序返回。我们知道,一个程序结束后,将CPU的控制权交还给使它得以运行的程序,我们称这个过程为:程序返回。DOS中的程序运行:DOS是一个单任务操作系统。一个程序P2在可执行文件中,则必须有一个正在运行
8、的程序P1,将P2从可执行文件中加载入内存后,将CPU的控制权交给P2,P2才能得以运行。P2开始运行后,P1暂停运行。而当P2运行完毕后,应该将CPU的控制权交还给使它得以运行的程序P1,此后,P1继续运行。,mov ax,4c00H int 21H,编写源程序,任务:编程运算 23。定义一个段实现处理任务程序返回程序结束段与段寄存器关联,汇编程序 assume cs:code code segment mov ax,2 add ax,ax add ax,ax mov ax,4c00h int 21h code ends end,语法错误和逻辑错误,语法错误程序在编译时被编译器发现的错误;容
9、易发现。aume cs:abc abc segment mov ax,2 add ax,ax add ax,ax end,语法错误和逻辑错误,逻辑错误程序在编译时不能表现出来的、在运行时发生的错误;不容易发现。,assume cs:abc abc segment mov ax,2 add ax,ax add ax,ax mov ax,4c00H int 21H abc ends end,程序经编译连接后变为机器码,操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存,并进行相关的初始化(比如:设置CS:IP指向第一条要执行的指令),然后由CPU执行程序。,程序执行过程的跟
10、踪,为了观察程序的运行过程,我们可以使用Debug。Debug 可以将程序加载入内存,并设置CS:IP指向程序的入口,但Debug并不放弃对CPU 的控制,这样,我们就可以使用Debug 的相关命令来单步执行程序,查看每条指令的执行结果。现在debug已将 1.exe 中的程序装入内存,接下来我们查看一下它的内容,可是我们查看哪里的内容呢?程序又被装入内存的什么地方?,程序执行过程的跟踪,首先用R命令看一下各个寄存器的设置情况:可以看到,Debug将程序从可执行文件加载入内存后,cx中存放的是程序的长度。1.exe 中程序的机器码共有15个字节。在DOS系统中.EXE文件中的程序的加载过程如下
11、:,EXE文件中的程序的加载过程,总结:程序加载后,ds中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0,则程序所在的内存区的地址为:ds:0;这个内存区的前256(100H)个字节中存放的是PSP,dos用来和程序进行通信。从 256字节处向后的空间存放的是程序,所以程序的物理地址是:SA16+0+256=SA16+1616=(SA+16)16+0 可用段地址和偏移地址表示为:SA+10:0 即cs=ds+10h,ip=0。,用U命令查看程序指令:,用T命令单步执行程序中的每一条指令,并观察每条指令的执行结果,到了 int 21,我们要用P命令执行:int 21 执行后,显示“Pr
12、ogram terminated normally”,返回到Debug中。表示程序正常结束。那程序返回到哪里呢?,程序执行过程的跟踪,注意:我们在 DOS中用“Debug 1.exe”运行Debug对1.exe进行跟踪时,程序加载的顺序是:command加载Debug,Debug加载1.exe。返回的顺序是:从1.exe中的程序返回到Debug,从Debug返回到command。使用Q命令退出Debug,则返回到command中,因为Debug是由command加载运行的。,标志寄存器(PSW)8086CPU中有一个很重要的16位标志寄存器,它包含9个标志位,由6位条件码标志(flag)和3位
13、控制标志构成。主要用于保存一条指令执行后,CPU所处状态信息及运算结果的特征。1条件标志:用来反映EU执行算术和逻辑运算以后的结果特征。2状态控制标志:用来控制CPU的工作方式或工作状态。,15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 01)条件标志(1)OF溢出标志:溢出时OF=1,否则OF=0。(2)SF符号标志:结果为负时SF=1,否则SF=0。(3)ZF零标志:结果为0时ZF=1,否则ZF=0。(4)CF进位标志:记录运算时从最高有效位产生的进位或借位值。当最高有效位有进位或借位时CF=1,否则置CF=0。(5)AF辅助进位标志:记录运算时第3位(字节运算)或
14、第7位(字运算)产生的进位或借位值。例如,执行加法指令时第3位有进位时AF=1,否则AF=0。,(6)PF奇偶标志:用来检验机器传送信息时可能产生的代码出错情况。当结果操作数中1的个数为偶数时PF=l,否则PF=0。2)控制标志(1)DF方向标志,当DF位为1时,每次操作后使变址寄存器SI和DI减量;当DF为0时,则使SI和DI增量。(2)IF中断标志,IF为l时,开中断,否则关中断。(3)TF陷阱标志,TF=1时,每条指令执行完后产生陷井,TF=0时,CPU正常工作不产生陷开。其中控制标志是系统程序或用户程序根据需要用指令设置的。而状态信息是由中央处理机根据计算结果自动设置的。,3)标志位举
15、例【例1】执行以下两数的加法操作,判断各标志位的状态。0010 0011 0100 0101+0011 0010 0001 1001 0101 0101 0101 1110执行以上操作后,各条件标志位的状态应为:OF=0(NV)SF=0(PL)ZF=0(NZ)AF=0(NA)PF=0(PO)CF=0(NV),Debug中标志位的符号表示,标志 1 0OF OV NVDF DN UPIF EI DISF NG PLZF ZR NZ AF AC NAPF PE POCF CY NC,【例2】执行加法操作。1010 1011 0000 0000+1111 1111 1111 1111 1010 10
16、10 1111 1111 执行操作后,各状态标志位的状态应为:CF PF AF ZF=SF=OF=【例3】执行加法操作。0110 0100 0000 0000+0110 0100 0000 0000 1100 1000 0000 0000执行以上加法操作后,各状态标志位的状态应为:CF=PF=AF=ZF SF=OF=,1,1,0,0,1,0,0,0,0,0,1,1,SF、CF、OF标志,SF符号标志位:主要是记录有符号数运算的结果符号,对于无符号数运算,该标志位没有意义。它记录指令执行后,结果为负,SF=1;结果为正,SF=0。有符号数与补码计算机中通常用补码来表示有符号数据。计算机中的一个数
17、据可以看作是有符号数,也可以看成是无符号数。关键看程序员需要的是什么数。,有符号数与补码,比如:00000001B,可以看作为无符号数 1,或有符号数1;10000001B,可以看作为无符号数129,也可以看作有符号数-127。示例 mov al,10000001B add al,1 结果:(al)=10000010B,SF=1,当作无符号数运算,那么add指令相当于计算129+1,结果为130(10000010B);当作有符号数运算,那么add计算-127+1,结果为-126(10000010B)。不管我们如何看待,CPU 在执行add等指令的时候,就已经包含了两种含义,也将得到用同一种信息
18、来记录的两种结果。关键在于我们的程序需要哪一种结果。,SF、CF、OF标志,OF溢出标志:记录有符号数运算结果是否正确。在进行有符号数运算的时候,如结果超过了机器所能表示的范围称为溢出,发生溢出,结果不正确。机器所能表示的范围是多少呢?-2n-1+2n-1-1比如:add al,3,那么对于 8 位的有符号数据,机器所能表示的范围就是-128127。add ax,3,对于16 位有符号数,机器所能表示的范围是-3276832767。,OF标志,注意,这里所讲的溢出,只是对有符号数运算而言,对无符号数没有意义比如 mov al,98 add al,99执行后将产生溢出OF=1。因为结果197超出
19、了机器所能表示的8位有符号数的范围:-128127指令:mov al,0F0H;0F0H,为有符号数-16的补码 add al,88H;88H,为有符号数-120的补码 执行后将产生溢出,结果错误。(al)=78H(120),OF=1。,SF、CF、OF标志,CF进位标志位,记录在进行无符号数运算的时候,运算结果的最高有效位向更高位有无进位值,或从更高位有无借位值。,CF和OF的区别,一定要注意CF和OF的区别:CF是对无符号数运算有意义的标志位;而OF和SF是对有符号数运算有意义的标志位。,比如:mov al,0F0H add al,88H add指令执行后:CF=1,OF=1。对于无符号数
20、运算,0F0H(240)+88H(136)有进位,CF=1;对于有符号数运算,0F0H(-16)+88H(-120)发生溢出,OF=1。那是不是有进位CF=1就一定产生溢出OF=1呢?,CF和OF的区别,再比如:mov al,0F0H(-16)add al,78H(120)add指令执行后:CF=1,OF=0。对于无符号运算,0F0H(240)+78H(120)有进位,CF=1;对于有符号数运算,0F0H+78H不发生溢出,OF=0。结果正确(al)=68H(104)可以看出,CF 和OF 所表示的进位和溢出,是分别对无符号数和有符号数运算而言的,它们之间没有任何关系。CF表示无符号数的溢出,
21、OF表示有符号数的溢出。,如何判断有符号数运算的溢出,设微型计算机字长为n,则两个带符号数的绝对值都应当小于2n-1,因而只有当两个数同为正或同为负,并且和的绝对值又大于2n-1时,才会发生溢出。两个正数相加,若数值部分之和大于2n-1,则数值部分必有进位Cp=1,而符号位却无进位Cs=0,这种溢出称为“正溢出”。两个负数相加,若数值部分绝对值之和大于2n-1,则数值部分补码之和必小于2n-1,Cp=0,而符号位肯定有进位Cs=1,这时称为负溢出,如何判断有符号数运算的溢出,补码运算过程也存在正常溢出,正常溢出是以2n(n为二进制的位数)为模的溢出,它被自然丢失,不影响结果的正确性。溢出只能出
22、现在两个同符号数相加或两个异符号数相减的情况下。判断规则:1、如果次高位向最高位有进位(或借位),而最高位向上无进位(或借位),则溢出。2、如果次高位无进位(或借位),而最高位有进位(或借位),也溢出。即采用双高位异或判断法:对8位有符号数,D6产生的进位(或借位)记为C6,D7产生的进位(或借位)记为C7,若C7C6=1,则OF=1。,举例:n=8 bit 有符号数(-128127),无符号数(0255),0 0 0 0 0 1 0 0+0 0 0 0 1 0 1 1 0 0 0 0 1 1 1 1带:(+4)+(+11)=+15 OF=0无:4+11=15 CF=0,带符号数和无符号数都不
23、溢出,0 0 0 0 1 0 0 1+0 1 1 1 1 1 0 0 1 0 0 0 0 1 0 1 带:(+9)+(+124)=-123 OF=1 无:9+124=133 CF=0,带符号数溢出,无符号数溢出,0 0 0 0 0 1 1 1+1 1 1 1 1 0 1 1 1 0 0 0 0 0 0 1 0带:(+7)+(-5)=+2 OF=0无:7+251=2 CF=1,带符号数和无符号数都溢出,1 0 0 0 0 1 1 1+1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 0 0带:(-121)+(-11)=+124 OF=1无:135+245=124 CF=1,Thank you very much!,本章到此结束,谢谢您的光临!,返回本章首页,结 束,