汇编语言学习知识点1

来源:互联网 发布:淘宝赚佣金方法 编辑:程序博客网 时间:2024/06/03 21:21

  • 寄存器(cpu)
汇编语言由以下3类组成:
1、汇编指令(机器码的助记符)
2、伪指令  (由编译器执行)
3、其它符号(由编译器识别)

8086CPU有14个寄存器 它们的名称为:AX、BX、CX、DX、SI、DI、SP、BP、 IP、CS、SS、DS、ES、PSW

8086CPU所有的寄存器都是16位的,可以存放两个字节。AX、BX、CX、DX 通常用来存放一般性数据被称为通用寄存器

AX可以分为AH和AL;BX可以分为BH和BL;CX可以分为CH和CL;DX可以分为DH和DL

地址加法器合成物理地址的方法:物理地址=段地址×16+偏移地址

需要注意的两点:
(1)段地址×16 必然是 16的倍数,所以一个段的起始地址也一定是16的倍数;
(2)偏移地址为16位,16 位地址的寻址能力为 64K,所以一个段的长度最大为64K。

段寄存器就是提供段地址的。8086CPU有4个段寄存器:CS、DS、SS、ES

CS和IP是8086CPU中最关键的寄存器,它们指示了CPU当前要读取指令的地址。CS为代码段寄存器;IP为指令指针寄存器

同时修改CS、IP的内容:

  jmp 段地址:偏移地址

  jmp 2AE3:3

  功能:用指令中给出的段地址修改CS,偏移地址修改IP。


仅修改IP的内容:

  jmp 某一合法寄存器

  jmp ax  (类似于 mov IP,ax)

  功能:用寄存器中的值修改IP。

  • 寄存器(内存访问)
将10000H(1000:0)中的数据读到al中
mov bx,1000Hmov ds,bxmov al,[0]

mov 寄存器名,内存单元地址

“[…]”表示一个内存单元, “[…]”中的0表示内存单元的偏移地址。执行指令时,8086cpu自动取DS中的数据为内存单元的段地址。

将al中的数据送入内存单元10000H
mov bx,1000Hmov ds,bxmov [0],al     
  • cpu提供的栈机制
8086cpu提供入栈和出栈的指令:

push ax: 将寄存器ax中的数据送入栈中;

pop ax: 从栈顶取出数据送入ax。

8086cpu的入栈和出栈操作都是以字为单位进行的。

8086CPU中,有两个寄存器:
段寄存器SS   存放栈顶的段地址
寄存器SP      存放栈顶的偏移地址
 任意时刻,SS:SP指向栈顶元素。

push ax
(1)SP=SP–2;
(2)将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。
pop ax
(1)将SS:SP指向的内存单元处的数据送入ax中;
(2)SP = SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。
注意:
出栈后,SS:SP指向新的栈顶 ,pop操作前的栈顶元素依然存在,但是已经不在栈中,当再次执行push等入栈指令后,会写入新的数据。

  • 栈顶超界问题
8086CPU不保证对栈的操作不会超界。这就是说, 8086CPU 只知道栈顶在何处(由SS:SP指示),而不知道读者安排的栈空间有多大。这点就好像 ,CPU 只知道当前要执行的指令在何处(由CS:SP指示)而不知道读者要执行的指令有多少。
所以在编程的时候要自己操心栈顶超界的问题 ,要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致的超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。
练习:
(1)将10000H~1000FH 这段空间当作栈,初始状态是空的;
(2)设置AX=001AH,BX=001BH;
(3)将AX、BX中的数据入栈;
(4)然后将AX、BX清零;
(5)从栈中恢复AX、BX原来的内容。
mov ax,1000Hmov ss,axmov sp,0010Hmov ax,001AHmov bx,001BHpush axpush bxsub ax,axsub bx,bxpop bxpop ax
  • 栈的综述
(1)8086CPU提供了栈操作机制,方案如下:
    在SS,SP中存放栈顶的段地址和偏移地址;
  提供入栈和出栈指令,他们根据SS:SP指示的地址,按照栈的方式访问内存单元。
(2)push指令的执行步骤:
  SP=SP-2;
  向SS:SP指向的字单元中送入数据。
(3)pop指令的执行步骤:
从SS:SP指向的字单元中读取数据; 
SP=SP-2。
(4)任意时刻,SS:SP指向栈顶元素。
(5)8086CPU只记录栈顶,栈空间的大小我们要自己管理。
(6)用栈来暂存以后需要恢复的寄存器的内容时 ,寄存器出栈的顺序要和 入栈的顺序相反。
(7)push、pop实质上是一种内存传送指令。
  • 段的综述
我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元。这完全是我们自己的安排。
我们可以用一个段存放数据,将它定义为“数据段”;
我们可以用一个段存放代码,将它定义为“代码段”;
我们可以用一个段当作栈,将它定义为“栈段”;
我们可以这样安排,但若要让CPU按照我们的安排来访问这些段,就要:
对于数据段,将它的段地址放在 DS中,用mov、add、sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据段来访问;
对于代码段,将它的段地址放在 CS中,将段中第一条指令的偏移地址放在IP中,这样CPU就将执行我们定义的代码段中的指令;
对于栈段,将它的段地址放在SS中,将栈顶单元的偏移地置放在 SP 中,这样CPU在需要进行栈操作的时候,比如执行 push、pop 指令等,就将我们定义的栈段当作栈空间来用。

可见,不管我们如何安排 ,CPU 将内存中的某段内存当作代码 ,是因为CS:IP指向了那里;CPU将某段内存当作栈 ,是因为 SS:IP 指向了那里
  • 第一个汇编程序
编程运算2^3
assume cs:abcabc segmentmov ax,2add ax,axadd ax,axabc endsend 
关于段结束、程序结束、程序返回



EXE文件中的程序的加载过程









0 0
原创粉丝点击