第三章 寄存器(内存访问)
在CPU中,用16位寄存器来存储一个字时,要用两个地址连续的内存单元来存放。低位字节存低地址单元,高位字节存高地址单元。把这个称之为字单元。(两个字节表示一个字)
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操作对象
但是它们不能对段寄存器进行操作(例如:add ds,ax ×)
在编程时,可以根据需要将一组长度为N(N<=64kb),地址连续,起始地址为16倍数的内存单元当做专门存储数据的内存空间,从而定义为了一个数据段。用ds存放数据段的段地址。
在这里,对栈的研究仅限于这个角度:栈是一种具有特殊的访问方式的存储空间。最后进入空间的数据最先出去
可以把栈看成物理空间的一个盒子
入栈就是将一个新的元素放到栈顶,出栈就是从栈顶取出一个元素
wsm要用栈? 栈能够存储一些目前不用但是会需要用到的数据,还可以用来实现列表循环,指令跳转等功能
如何操作?
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。产生一个存储源程序的文本文件。第二步:对源程序进行编译连接,编译产生目标文件,连接后生成可在操作系统中直接运行的可执行文件(包含程序数据,相关描述信息)。第三步:执行可执行文件。
第五章 [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]
计算单元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.那应该如何计算?
关键点:类型的匹配和结果不超界
实例
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