汇编语言_大灰狼_第1页
汇编语言_大灰狼_第2页
汇编语言_大灰狼_第3页
汇编语言_大灰狼_第4页
汇编语言_大灰狼_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、CPU的结构CPU对设备的读写1、 程序是如何运行的?· 双击程序à应用程序载入内存àCPU找到应用程序在内存中的位置à通过某种途径把程序传送给CPUCPU通过一些很细的线与外围设备进行通讯,这些线叫做总线CPU与内存通信的线叫做地址总线(通过这里将应用程序在内存中的位置的地址传递给CPU)在找到应用程序在内存中的位置之后呢,还得想办法把应用程序的内容传递给CPU,这个途径成为数据总线与CPU连接的除了地址总线和数据总线之外,还有一个是控制总线,即:CPU用来控制外围设备的(如硬盘、光驱、声卡等)2、CPU是如何传输数据的?CPU运行起来时0101的数据

2、,这些线只能传输两种信号,即0和1信号,高低电平分别是1和0信号。8086CPU有20条地址总线,从CPU连到内存,则CPU的最大寻址范围就是2=1024KB=1MB,即8086最大寻址范围是1MB 假设CPU要到内存中找数据,则CPU要把应用程序的地址传送给内存,然后内存通过地址找到相应的数据,再通过数据总线把内容传输给CPU。其中CPU中有一个内存控制器,它会根据CPU传递过来的地址找到相应的数据内容。控制总线用来干什么呢?有的时候CPU要读内容,有的时候要写内容,则是通过控制总线执行什么动作。CPU就是通过这三种总线与外围设备通讯的。3、总线的宽度所谓总线的宽度就是指CPU有多少根线连接

3、到内存当中,或者说地址总线的宽度决定了CPU的最大存储范围,也可以说CPU是多少位的就是多大的寻址范围。比如说CPU是32位的话,最大的寻址范围就是2的32次方就是4G内存,所以即便你安装了8G的内存,另外4G是无法利用起来的。2 = 1MB 4、继续探讨CPU执行程序当内存将数据送到CPU之后,是不是立即就开始执行程序呢?不是的,CPU是先将程序的数据放入寄存器,然后再从寄存器里取出数据来执行 寄存器概念5、那什么事寄存器?它有什么作用?答:存放CPU要执行的数据或指令寄存器分为:通用寄存器和段寄存器寄存器知识补充:1数据寄存器(或称通用寄存器)  数据寄存器包括AX,BX,CX,

4、DX四个通用寄存器,他们可以以字16位的形式使用,也可以以字节8位的形式使用。  以字形式使用时四个通用寄存器称为AX,BX,CX,DX,以字节形式使用,高八位通用寄存器称AH,BH,CH,DH。低八位称AL,BL,CL,DL。  这四个都是通用寄存器,又可用于专用的目的。  AX做累加器用(ACCUMALATOR)BX在计算存储器地址时,经常用做基地址寄存器,所以又称基址寄存器。(BASE)  CX(COUNT)可用做通用寄存器。此外,在循环( LOOP)和串处理指令中用做隐含的计数器。  DX(DATA)在做双字长的运算时,把DX

5、和AX组合在一起存放I/O端口地址。  2,指针及变址寄存器  他们包括SP,BP,SI,DI四个16位寄存器。他们可以象数据寄存器一样在运算过程中存放操作数,单他们只能以字16位为单位使用。  SP(STACK POINTER)堆栈指针寄存器;  用来指示堆栈的栈顶的偏移地址,与SS堆栈段寄存器形成栈顶存储单元的物理地址。  BP(BASE POINTER)基址指针寄存器。  用来指示堆栈中某个数据区的偏移地址-基地址。  SI(SOURCE INDEX)源变址寄存器;  DI(DE

6、STINATION INDEX)目的变址寄存器;  3,段寄存器  包括CS,DS,SS,ES四个16位段寄存器  CS(CODE SEGMENT)代码段寄存器  SS(STACK SEGMENT)堆栈段寄存器  DS(DATA SEGMENT)数据段寄存器  ES(EXTRA SEGMENT)附加段寄存器  8086/8088采用存储空间的分段技术来解决寻址1M字节的存储空间。这些段寄存器的内容和有效的地址偏移量(称偏移地址)一起可确定内存的存储单元的物理地址。CS控制程序

7、区DS和ES控制数据区,SS控制堆栈区。  4控制寄存器  分为两个16位的寄存器IP和PSW。  IP(INSTRUCTION POINTER)指令指针寄存器;他用来存放代码段中的偏移地址。程序运行中始终指向下一条指令的首地址。计算机就是用IP寄存器来控制指令序列的执行流程的  PSW(PROGRAM STATUS WORD)程序状态字寄存器或称标志寄存器;  由状态码标志和控制标志构成,  OF溢出标志;运算结果超出机器能表示的数值范围称溢出OF=1,否则OF=0;  SF符号标志;运算结果

8、的符号为负时置1否则置0  ZF;零标志  CF进位标志  AF辅助进位标志  PF奇偶标志  DF方向标志  DF=1每次操作后使SI和DI减量,使串处理指令向低地址方向进行  IF中断标志  TF跟踪标志  控制标志是由系统程序或用户程序根据需要用指令来设置的。AX寄存器(8086寄存器的一种.成为累加寄存器)AX寄存器是通用寄存器,是专门用来存放数据的寄存器。高8位成为AH,低8位成为AL。它是如何组织数据的?AX中有两个字节字节:用8个二进制数表示一个字节字:用两个字节表示一个字,即16位二进制数

9、据双字:两个字表示,即32位二进制数当然还有4字的。CPU内部是由哪些部件构成的?1、 寄存器2、 运算器(+-*/)3、 控制器,控制各器件运行,发送一些命令(各个运算器做什么有这个决定)4、 内部总线连接各种器件,在它们之间进行数据传输物理地址表示方法8086主板地址线20根进行寻址必须一次传20位二进制数,但是CPU最大一次只能床16个二进制位,如何解决?比如有两个小纸条,每张最低只能写三位数字,要求用这两张纸条来表示一个四位数字CPU也是类似于这样进行处理的。CPU用地址加法器完成这样的功能如上图,234成为基地址,23成为偏移地址CPU用基地址+偏移地址得到实际物理内存地址内存地址的

10、表示方法:基地址:偏移地址=实际内存地址计算方法: 实际内存地址 = 基地址 * 16 + 便宜地址解释:我们人是基于十进制运算的,要想后面加一个0即加一位,所以用234*10 然后加23,而8086计算机是基于16进制的,所以要乘以16然后加上偏移地址具体例子:1402:100;1402H * 16(10进制,16基址的10H)+ 0100H = 14120H其中H表示16进制。 CPU如何对内存进行逻辑的分段处理1000H转化为基地址:偏移地址1000H:0000寄存器分为公用寄存器和段寄存器,通用寄存器用来存放普通的数据,而段寄存器与这里的段地址是一个概念,就是存放基地址的。 段地址和偏

11、移地址CS和IP寄存器主要内容:CS、IP寄存器;debug命令的使用;内存访问1、 程序被载入内存后,CPU是从哪里开始执行程序代码的?在C语言中main函数是第一个被执行的那么在汇编语言中是从哪里开始的呢?我们知道,段地址*16 + 偏移地址 = 实际物理地址CS(code segment)寄存器保存了要被执行的代码的基地址寄存器保存了要被执行代码的偏移地址寄存器别名为指令指针寄存器也就是说:CS * 16 + IP = 实际地址2、Debug工具什么是debugeDebug是DOS、Windows都提供的实模式程序调试工具可以查看CPU各种寄存器中的内容和机器码级跟踪程序的运行Debug

12、命令的使用Debug的R命令用来查看和改变各个寄存器内容Debug的D命令查看内存中的内容屏幕上的内容有3部分:左边显示的是用“基地址:偏移地址”即“CS:IP”的形式表示内存内容。中间是用16进制的形式表示内存内容。右边是由ASCII的形式表示内存内容如果想查看某个寄存器的内容,可以在d的后面加相应的寄存器:0000然而用16进制表示的内容我们看不懂,如果希望用汇编语言显示,则可以用下面的命令Debug的U命令将内存机器码转为汇编指令下面用u cs:0100表示查找cs寄存器其中左边是基地址:偏移地址。中间是16进制表示的操作指令。右边两行表示的是汇编指令Debug的T命令跟踪代码运行Deb

13、ug的A命令以汇编指令格式在内存中写入指令以上是把1234赋值给ax寄存器验证:CS IP指定的存地址中的内容就是CPU要执行的内容第一步:看一下CS中当前的内容之后我们用T命令跟踪程序的执行看出:第一个cs=0B6F IP=0103 即ES:命令第二个CS=0B6F IP=0108 即JZ命令第三个 CS=0B6F IP =010A 即CALL命令通过相邻两个ip的差可以算出上一个指令所占用的空间是多大下面看一个例子:int number ;int main()int a = 10 ;if(a>0)a+ ;return 0 ;程序分为:数据段,,代码段,堆栈段其中数据段用来存放应用程序

14、的全局变量,如本例的int number代码段:if(a>0) a+ ;堆栈段:int a = 10;局部变量如果我们想为全局变量赋值,我们必须先找到其在内存中的地址 CPU根据什么指定内存中的哪些数据是我们定义的全局变量?即 DS寄存器(内存访问)CPU是根据DS(Data Segment)这个寄存器和任意一个通用寄存器的值或其他数值组成数据段的物理地址如:DS :0 或者 DS : BX第一个表示方法是将一个内容直接保存在DS寄存器的一个地址中第二种表示时将一个内容保存到另一个BX通用寄存器中当然还有其他表示方式上面两种方式表示的都是物理内存中具体的地址因为全局变量保存在内存地址中,

15、因此我们要访问这些物理地址内存的表示方法:在汇编语言中表示内存的两种写法mov ds:13ABH,1234H即把1234放入内存地址ds*16 + 13AB中mov 13ABH ,1234H第二种更常见堆栈主要内容:栈的概念 ss寄存器和sp寄存器 post和pop指令栈的数据结构:栈是一种具有特殊的访问方式的存储空间,它的特殊性就在于,最后进入这个空间的数据,最先出去。数据出栈:在内存中栈是从高字节向低字节存放数据堆栈段存放的是函数的局部变量,数据段存放的是全局变量ss、sp寄存器同代码段和数据段一样,CPU如何知道一段内存空间被当做栈使用?Cpu是根据ss这个段寄存器和sp这个通用寄存器来

16、感知堆栈段的存在。也就是说,cpu从ss中取出一个值,再从sp中取出一个值,ss * 16 + sp 所指向的那个内存单元即是栈内存段寄存器ss存放栈的基地址,sp存放的是栈顶的偏移地址执行入栈和出栈的时候,如何知道哪个单元是栈顶单元?cpu规定,任何时候ss:sp都指向站顶元素push指令的执行过程:如果ax=1234h。即ax寄存器中存放的是1234这个16进制的数,现在想把它放入栈中,假设现在是空栈,ss:sp指针指向栈顶,此时,将34压入栈低,12放到栈顶,即先放低字节的数,再放高字节的数,最后ss:sp指针指向12具体过程:push ax(1) 将ax中的内容送入ss:sp指向的内存

17、单元处,ss:sp此时指向新栈顶(2) Sp = sp -2 ;通过这条指令使指针往上移(3) 入栈数据是从高字节往低字节进行排列的,即最上面是高字节。出栈则相反Pop ax将ss:sp指向的内存单元处的内容赋值给ax寄存器,然后sp+2.,ss:sp此时指向新的栈顶出栈数据是从低字节往高字节排列操作解释:a命令,用汇编语言的形式在内存中写入指令mov ax ,1234将1234赋值给ax寄存器之后分别是:将7ba1、2213分别写入bx、cx寄存器push ax:将ax中的数据入栈之后分别是:将bx、cx入栈pop ax:将ax出栈之后分别是:将bx、cx出栈由于入栈顺序和出栈顺序相反,所以

18、将三个数据经过这样的处理之后,三个数字的顺序将反着输出。下面用t命令跟踪程序验证:可以发现前三步分别对ax、bx、cx赋值了,显著的变化时ax,bx,cx的值变了,而且ip的值每次加3继续验证:这三步分别是将ax,bx,cx入栈,入栈时会将数据放到栈中,显著的变化时sp的值每次减3下面继续验证,出栈:这三步进行了出栈操作,可以发现的显著变化时sp每次加3。而且ax的值和cx的值对换了关于栈的疑问1、 当栈满时再进行入栈会发生什么情况?2、 当栈空时再使用出栈指令会发生什么情况?栈顶越界是危险的!因为我们既然将一段空间安排为栈,那么在栈空间之外的空间里很可能存放了具有其他用途的数据和代码,这些数

19、据或代码可能是我们自己的程序,也可能是别的程序中的ss:sp寄存器配合指定了栈顶位置,可是如何保证在入栈和出栈时栈顶不会超出栈空间?8086CPU不保证对栈的操作不会越界也即:8086CPU只知道栈顶在何处,(由ss:sp指示),而不知道读者安排的栈空间有多在。第一个Hello World汇编程序汇编集成开发环境如何利用汇编语言编写一个简单的Hello world应用程序?1、 汇编语言中变量又是如何定义的?2、 汇编语言如何把要显示的内容输出到屏幕上呢?3、 汇编语言编写的程序如何进行调试?编写包含多段的应用程序msg是全局变量,应该放在应用程序的数据段中打印msg变量的是程序代码,应该放在

20、应用程序的代码段中4、 如何让汇编语言知道我们编写的程序是有多个段组成的?assume关键字assume关键字表示用来假设某一段寄存器和程序中的某一个用segmentends定义的段相关联 (假设的意思)db指令那么如何在数据段中定义全局变量msg并赋初值?使用db(define byte)指令来定义字节的内容,语法:label db initalizer,initializer,initializerlabel 表示任选标号,相当于C语言的变量名db表示define byte 定义个字节数据initalizer表示初始值msg db “hello world”这里写单引号也行,在汇编中都一样

21、上面的语句相当于C语言的:char msg = “hello world”下面研究如何打印出上面定义的数据观察上面的内存地址空间图,我们说:只要我们把“hello world”这个字符串拷贝到显存地址空间,我们的显卡就自动地把它显示到屏幕上那么在CPU中哪一段地址空间是显存地址空间呢?CPU已经为我们安排好了!其中显示地址中又分为很多种显示模式vga显存地址空间在内存地址空间中,B8000HBFFFFH共32的地址空间80*25(列X行)彩色字符模式(vga)的显示缓冲区,只要向该地址空间写入数据,写入的内容就立刻显示到屏幕中8个byte可以表示一个字符,紧跟其后的是8个byte表示颜色,即用

22、16位二进制数表示一个颜色的字符VGA的英文全称是Video Graphic Array,即显示绘图阵列。VGA支持在640X480的较高分辨率下同时显示16种色彩或256种灰度,同时在320X240分辨率下可以同时显示256种颜色. 肉眼对颜色的敏感远大于分辨率,所以即使分辨率较低图像依然生动鲜明。VGA由于良好的性能迅速开始流行,厂商们纷纷在VGA基础上加以扩充,如将显存提高至1M并使其支持更高分辨率如800X600或1024X768,这些扩充的模式就称之为VESA(Video Electronics Standards Association,视频电子标准协会)的Super VGA模式,

23、简称SVGA,现在的显卡和显示器都支持SVGA模式。不管是VGA还是SVGA,使用的连线都是15针的梯形插头,传输模拟信号高亮的意思是粗体显示vag显存地址空间在80*25彩色模式下显示器可以显示25行80列。每个字符可以有256种属性(背景色前景色闪烁等)一个字符在显存中占两个字节,分别存放ASCII码值和属性显示缓冲总共分为8页,每页4KB,显卡可以显示任意页内容一般情况下显示第0页内容即B8000HB8F9FH(4K的空间)到目前学过的8086段寄存器有CS(CODE SEGMENT)代码段寄存器  、SS(STACK SEGMENT)堆栈段寄存器 

24、; 、DS(DATA SEGMENT)数据段寄存器 这几个寄存器都有它自己特定的功能,我们不能随便给它们赋值,那怎么办呢?CPU还为我们分配了一个ES(EXTRA SEGMENT)寄存器,叫做附加段寄存器 ,这个寄存器专门存放我们的段地址,即B800H这个段地址存放到这个ES寄存器中:mov es,0b800h上句说明:给es寄存器赋值B800,因为是16进制,所以后面加一个H,为了CPU能辨认这是一个16进制的数,所以前面加了一个0,当16进制数第一个数字不是字母的时候就不用加0了但是CPU规定,我们不可以直接将一个常量直接赋值给一个ES寄存器,所以必

25、须通过一个中间的通用寄存器中转一下:mov bx,0b800hmov es,bx现在我们再把hello world的一个个的拷贝到以ES为段地址,以0为偏移地址的寄存器中,现在用一个循环来做这个工作汇编中的循环 loop关键字如何把我们定义的字符一个个的拷贝到显存的缓冲区中?语法:标号:指令1指令2loop 标号那么循环次数怎么指定呢?这个数字存放在CX寄存器中,循环的次数由CX寄存器中的数据来决定,循环完一句自动减一。循环内部如何实现功能?如何获得在数据段中的每一个内容?这涉及到内存访问1、 我们知道hello world属于数据段内容,那么其中每个字符都可以通过数据段地址加上偏移地址获得2

26、、 汇编中数据段地址存放在ds寄存器中,那么要获得数据段第一个字节内容就要如下表示:ds:0或ds:si第一个表示获得段地址在ds中,偏移地址是0.在循环中偏移地址应该是可变的,因此应放在一个寄存器中si寄存器相当于通用寄存器把H从数据段ds中拷贝到es寄存器中的代码如下:mov es:0,ds:0 在loop中应该用变量替换0mov si ,0/初始化为0mov bx,0s:mov es:bx,ds:si但是汇编中不支持这样的语法,因为这只指定了初始地址,没有指定结束语地址所以也需要一个中间的寄存器导一下s:mov ax,dssimov es,ax但是一个字符是8位的,但是ax是16位的,此

27、时我们只用其一半就可以al和ah寄存器设计80*86cpu时,为了能够完全兼容8088cpu(8位cpu), 我们可以把通用寄存器AX,BX,CX,DX分别当作两个8位寄存器来使用AX寄存器可以分成AH和AL两个8位寄存器,其余类似s:mov al,dssimov es,al然后我们知道,字符的属性紧跟在字符后面,我们用红底绿字01000010bmov ah, 01000010bmov es:bx+1,ah然后si加1inc sibx要加2add bx,2最后循环结束loop s代码段和数据段我们只是人为的规定了Assume cs:code,ds:data但是编译器不知道,因此必须明确指定现在

28、我们为程序划分出了代码段和数据段,那么CPU是否就能够执行代码段中的指令和数据中的数据呢?答案是否定的,因为这是我们人为给予的标记,方便我们阅读CPU却完全不知道解决:把标记了data的数据段地址赋给ds 段寄存器,mov ax,datamov ds,ax此时编译器就知道了data代表了数据段代码段CPU可以自动获得代码段地址CPU可以获得代码段的段地址,却不知道其偏移地址,此时可以在代码首行加入一个start关键字,在最后加一个end start屏幕暂停:mov ax,4c00h int 21h所有代码assume cs:code,ds:datadata segmentmsg db &quo

29、t;hello world"data endscode segmentstart:mov ax,datamov ds,axmov bx,0b800hmov es,bxmov cx,11mov si,0mov bx,0mov ah,01000010b s:mov al,ds:si mov es:bx,al mov es:bx+1,ah inc si add bx,2 loop s mov ax,4c00h int 21hcode endsend start中断1、 中断的概念a) 什么是中断?任何一个通用CPU,比如8086都具备一种能力,可以执行完成当前正在执行的指令后,检测到从CP

30、U外部或内部产生的一种特殊信息,并立即对接收的信息进行处理。这种信息称之为中断信息中断的意思是指:CPU不再接着(刚刚执行的指令)向下执行,而是转去处理这个特殊信息2、关于中断的疑问:中断发生时CPU如何找到中断处理程序?中断处理程序有很多种,那么每个中断程序存放在哪里?中断处理完成之后,CPU如何继续运行之前的中断的程序?中断向量表中断向量表在内存中保存,其中存放着256个中断所对应的中断处理程序的入口,如下0号中断对应的中断处理的入口地址1号中断对应的中断处理的入口地址2号中断对应的中断处理的入口地址3号中断对应的中断处理的入口地址那么中断向量表一般存放在哪里呢?CPU规定了内存中的某个地址专门存放中断向量表中断向量表一般保存在内存0000 :0000到 0000:03FE那么在中断向量表中一表项占多少内存空间?一个表项存放一个中断向量,也就是一个中断程序入口地址,这个入口地址包括段地址和偏移地址因此每个表项占两个字的空间,高地址存放段地址,低地址存放偏移地址 考虑一个问题:当CPU执行完中断处理程序后必须返回继续执行原来的命令,那么CPU根据什么能够回到原来执行代码中断执行?遇到中断时CPU把CS和IP内存入栈暂时保存起来,等

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论