汇编语言归纳总结(二)

第三章 寄存器(内存访问)

内存中字的存储

在CPU中,用16位寄存器来存储一个字时,要用两个地址连续的内存单元来存放。低位字节存低地址单元,高位字节存高地址单元。把这个称之为字单元。(两个字节表示一个字)

DS和[address]

8086cpu中有一个DS寄存器,专门用来存放要访问数据的段地址

mov指令的两种传送

  • 将数据直接送入寄存器

  • 将一个寄存器中的内存送入另一个寄存器

但8086cpu不允许直接将数据送入ds中,所以需要一个寄存器做中转。先将数据送入普通寄存器中,如ax,bx,再将ax中的数据送入ds。

例如
mov ds,1000H ×

mov ax,1000H
mov ds,ax     √

字的传送

8086cpu是16位结构,有16根数据线,所以一次性传送16位的数据,也就是一个字。

mov,add,sub

mov操作对象

  • mov 寄存器(内存单元/段寄存器),数据(寄存器/内存单元)

add和sub操作对象

  • add 寄存器, 数据(寄存器/内存单元)
  • sub 寄存器(内存单元), 数据(寄存器/内存单元)

但是它们不能对段寄存器进行操作(例如:add ds,ax ×)

数据段

在编程时,可以根据需要将一组长度为N(N<=64kb),地址连续,起始地址为16倍数的内存单元当做专门存储数据的内存空间,从而定义为了一个数据段。用ds存放数据段的段地址。

在这里,对栈的研究仅限于这个角度:栈是一种具有特殊的访问方式的存储空间。最后进入空间的数据最先出去

可以把栈看成物理空间的一个盒子

入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素

wsm要用栈? 栈能够存储一些目前不用但是会需要用到的数据,还可以用来实现列表循环,指令跳转等功能

如何操作?

  • push ax     将ax中数据送入栈中
  • pop ax      从栈顶取出数据送入ax

8086cpu入栈出栈都是以字为单位进行,cpu如何知道哪里是栈段哪里是栈顶?

像指明数据段和指令一样,用特殊寄存器表明。

段寄存器SS和寄存器SP,段地址放SS,偏移地址放SP。任意时刻,SS:SP指向栈顶元素

  • push ax
    sp=sp-2,ss:sp指向当前栈顶前面的单元,以当前栈顶前面的单元为新栈顶
    将ax中的内容送入ss:sp指向的内存单元处,ss:sp指向新栈顶

  • pop ax
    将ss:sp指向的内存单元处的数据送入ax
    sp=sp+2,ss:sp指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶

如果入栈的数据超过了栈空间,或是在栈空的时候出栈,都会发出栈顶超界问题,它们会将栈外空间的数据覆盖,或是提出站外空间数据。

第四章 程序写出到执行

一个汇编语言程序从写出到执行简要过程,第一步:编写汇编源程序,记事本,edit。产生一个存储源程序的文本文件。第二步:对源程序进行编译连接,编译产生目标文件,连接后生成可在操作系统中直接运行的可执行文件(包含程序数据,相关描述信息)。第三步:执行可执行文件。

下载好DOSBOX后就可以编译连接源程序了
汇编语言归纳总结(二)_第1张图片

第五章 [BX]和loop指令

为了描述简洁,用一个()来表示一个寄存器或一个内存单元中的内容。用[ ]表示内存单元的偏移地址,idata表示常量。

bx是专门用来存放偏移地址的寄存器,loop是一条循环指令。loop进行两步操作,1.(cx)=(cx)-1 2.判断cx中的值,不为0则转至标号处执行,为0则向下执行。cx是专门用来存放循环次数的寄存器

任务:编程计算2^12结果存放在ax中
思路:2^12可理解为重复12条add ax,ax。可用loop指令简化我们的程序
实例程序:
assume cs:code
code segment
    mov ax,2
    mov cx,11
s: add ax,ax
    loop s
    mov ax,4c00h
    int 21h
code ends
end

分析
(1)标号
标号表示标识一个地址
(2)loop s
CPU执行loop s的时候,进行两步操作:
(cx)=cx-1
判断cx中的值,不为0则转至标号s所标识地址执行,若为0则执行下一条指令

循环功能要点总结
1.在cx中存放循环次数
2.loop指令标号所标识地址放前面
3.要循环执行的程序段,写在标号和loop中间

[ ]讲解

指令 mov ax,[0] 表示将ds:0处数据送入ax中,但在汇编源程序中,指令“mov ax,[0]”被编译器当做指令“mov
ax,0”处理。那么应该怎么解决呢?

  • 将偏移地址送入bx寄存器中,用[bx]的方式来访问内存单元。
    mov ax,2000h
    mov ds,ax
    mov bx,0
    mov al,[bx]

  • [ ]中直接给出内存单元的偏移地址,并在[ ]的前面显式地给出段地址所在的段寄存器
    mov ax,2000h
    mov ds,ax
    mov al,ds:[0]

loop和[bx]联合应用

计算单元ffff:0~ffff:b单元中数据的和,结果存在dx中

写程序之前需要思考的问题

1.结果是否会超出dx所能存储的范围?
ffff:0~ffff:b内存单元中是字节型数据,范围在0-255之间,12个这样的数据相加不会大于65535,可以存放

2.能否直接将ffff:0~ffff:b中的数据累加到dx中?
不行,ffff:0~ffff:b中数据是8位的(字节型数据),不能直接加在16位寄存器中

3.能否将ffff:0~ffff:b中的数据累加到dl中,并设置(dh)=0,从而实现累加到dx?
不行,dl是8位寄存器,能容纳数据在0~255之间,可能造成进位丢失

4.那应该如何计算?
关键点:类型的匹配和结果不超界

  • (dx)=(dx)+内存中的8位数据
  • (dl)=(dl)+内存中的8位数据
    将内存单元中的8位数据赋值到一个16位寄存器ax中,再在ax中的数据加到dx上

实例
assume cs:code
code segment
    mov ax,0ffffh
    mov ds,ax
    mov bx,0
    mov dx,0
 s:mov al,[bx]
    mov ah,0
    add dx,ax
    inc bx
    loop s
code ends
end

你可能感兴趣的:(汇编语言)