《汇编语言》第三版书籍阅读总结(第三章,第四章)

本文详细介绍了8086CPU的内存地址结构,字单元概念,DS和[address]的使用,以及基本的mov,add,sub指令。此外,还涵盖了CPU提供的栈机制、汇编程序的编译与执行过程,重点讨论了如何通过debug进行程序跟踪和DOS加载程序的机制。
摘要由CSDN通过智能技术生成

第一次记录时间: 2024.4.27 星期六 天气阴

3.1  字单元

字单元就是存放一个字型数据的内存单元。不同的CPU的字单元长度不同,对于CPU8086来说,字长为16,。由于一个内存单元存放的是一个字节,所以一个字单元由两个内存单元组成。

高地址的内存单元存放高位的数据,低位地址的内存单元存放低位的数据。

注意我们将起始地址为N的字单元简称为N地址字单元

而且注意CPU并不区分字单元,只根据起始地址+字单元的长度来确定

起始地址为0的字单元由地址为0,1的两个内存单元组成,同样也可以起始地址为1的字单元,由地址为1,2的两个内存单元组成。

3.2 DS和[address]

CPU要访问一个内存单元,必须知道内存单元的地址。在CPU8086中内存地址由段地址和偏移地址组成,可以用DS+[ ]来表示。

DS数据段寄存器,里面存放的是要访问数据的段地址

[ ] 表示的是要访问数据的偏移地址,在使用[ ] 时CPU会自动将ds中的值当做段地址

所以以后看到[ ] 就要去找ds的值(注意在汇编语言中不区分大小写)

但是注意ds中是段地址,在计算物理地址时是段地址*16+偏移地址来算的,所以注意给ds所附的值是段地址(在十六进制下段地址的位数比起始地址低一位,而且起始地址的最后一位一定是0

mov bx,1000H
mov ds,bx
mov al,[0]
//最后一条意思是将起始地址为(起始地址是10000H,偏移地址是0)的字单元里面的值赋给al
//注意是不能直接将值赋给段寄存器的,这是CPU不允许的
mov ds,1000H
//如果想要给ds赋值,必须想最上面代码一样,先将值赋给一个普通寄存器,再赋给段寄存器

3.3 mov,add,sub指令

mov,add,sub操作对象有直接的数值,还有寄存器,段寄存器,内存单元(就是[  ] )

注意段寄存器不能直接与数值进行操作

3.4 CPU提供的栈机制

 8086CPU提供入栈和出栈指令,其中最基本的两个是PUSH(入栈)和POP(出栈)

push ax 是将ax的值压进栈中        pop ax表示从栈顶取出数据送入ax

注意:栈是以字为单位进行操作

CPU如何定位:

是通过段寄存器SS和寄存器SP,栈顶段地址存放在SS中,偏移地址存放在SP中。

任意时刻 SS:SP指向栈顶元素。PUSH和POP指令时CPU从SS:SP中获得栈顶地址

注意:

栈是否发生越界,CPU并不保证,所以需要我们在操作时注意越界问题

栈元素出栈后,SP作为栈指针向下走,但是出栈的元素值其实还在那里,只是不在栈中,待后面的PUSH输入元素将其覆盖

POP和PUSH操作内存地址 [ ] 这样的时注意内存地址的段地址是默认在ds中的,和ss不同

注意栈这样的分出一个段来操作是人为规定的,CPU并不区别对待

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

程序员先用汇编语言编写汇编程序,可以通过记事本等文本编辑器,就是为了产生一个储存源码的文本文件。  

然后对文件进行编译生成对象文件,然后再进行连接,生成在操作系统中可以直接运行的可执行文件。(可执行文件包含两个部分:程序(从源程序中汇编指令翻译过来的机器码)和数据,还有相关描述信息(比如程序多大,占用多少空间)) 

最后在从操作系统中执行可执行文件中的程序,操作系统根据可执行文件中的描述信息,将可执行文件的机器码和数据加载入内存,并进行相应的初始化(设置CS:IP指向第一条指令),然后由CPU进行执行程序

4.2 源程序

一段简单的汇编语言源程序

assume cs:codesg

codesg segment
    
        mov ax,0123H
        mov bx,0456H
        add ax,bx
        add ax,ax
        
        mov ax,4c00H
        int 21H

codesg ends

end

在汇编程序中有两种指令:汇编指令,伪指令

汇编指令就是有对应的机器指令,转化为机器指令被CPU执行

伪指令就是没有对应的机器指令,不能被CPU执行,只能由编译器执行

1.伪指令

(1): 

segment和ends是一对成对使用的伪指令。segment和ends的功能是定义一个段,segment表示这个段开始,ends表示这个段结束。

一个段必须有一个名称来标识,使用格式:

段名 segment

段名 ends

(2):

end,这个end与ends是不一样的。这个end是整个程序结束的标志,而ends只是一个段结束的标志。每个程序必须以end结尾,表示程序结束

(3):

assume是将某一个段寄存器和程序中某一个用segment,ends表示的段关联起来。在需要时,编译程序可将段寄存器和某一个具体的段相连

如上所示,用assume cs:codesg将用作代码段的codesg段和CPU中的段寄存器cs联系起来,这样这个codesg段就会拥有cs的特性,用于储存程序

我们将源程序文件中的所有内容称为源程序,将源程序中最终由计算机执行处理的指令数据称为程序。所以只有汇编指令部分才是程序。

请注意:

一个汇编程序是由多个段组成,这些段被用来存放指令,数据,甚至当做栈空间使用。

一个有意义的汇编程序至少有一个段,这个段用来存放代码

一个程序结束后,将CPU的控制权交还给使它得以运行的程序,这个过程叫做程序返回,这个操作是由mov ax,4c00H int21H两条指令实现,我们暂时不必去理解这两条指令,记住作用即可 

2.以简化的方式进行编译和连接 

在编译一个源程序之前首先要找到一个相应的编译器,我们课程中采用微软的masm编译器

直接指明编译器 和 编译文件的位置进行编译,注意这个;号是自动补全的作用

link连接也是一样的

但是编译完成,我们看不到任何结果 ,就和没有运行一样的,因为我们并没有向显示器输出任何信息。

那么masm后将asm文件生成为obj文件,obj文件在连接后生成了exe文件。但是我们如果要执行exe文件,必须将其放到内存中去使它运行,那么这个放到内存中去使其运行这个操作是谁完成的

所以由上面我们知道是操作系统的shell程序(也是DOS中的command)将exe文件弄到内存中去,并初始化让CPU运行。

但是我们希望对程序执行过程进行跟踪,所以可以用debug对exe文件的执行进行流程跟踪

首先,程序加载后,ds是存放了程序所在地址空间的 段地址,这个内存区偏移地址位0,所以

程序所在的内存区地址为ds:0

内存区前256个字节存放的是PSP(程序段前缀),是DOS用来和程序通信的,从256字节后面存放的就是程序,这个地址就是CS:IP了。

图中ds为075A与CS076A差了100H,正好为256

后面通过t来单步执行程序中的每一条指令,并观察结果,到了int21,我们要用P命令执行

这时还在debug下,所以程序运行后输入q退出debug 

这里还有个特点:

我们知道DOS中是command 将程序加载入内存的,所以是command首先将debug程序加载,然后debug加载1.exe。返回的顺序是:从1.exe返回到debug,debug返回到command

  • 55
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值