"字"在寄存器中的存储
- 8086是16位CPU,8086的字长为16bit
- 一个字可以存在一个16位寄存器中
字的高位字节存在这个寄存器的高8位寄存器
字的低位字节存在这个寄存器的低8位寄存器
通用寄存器
- AX 累加器
- BX基址寄存器
可以用来储存偏移地址 - CX计数寄存器
存放循环次数 - DX数据寄存器
- 数据的存储
十六位寄存器存储十六位的数据
最大值:2的16次方 - 1
先把要储存的数据转化成十六进制,再根据十六进制和二进制之间的转换关系转换成二进制储存到寄存器中20000D -- 4E20H -- 0100111000100000B
- 因为8086上一代CPU中的寄存器都是8位的,为了保证兼容性,可以把通用寄存器分为两个独立的8位寄存器使用
变址寄存器
- SI 源变址寄存器
- DI 目的变址寄存器
- 常执行与地址有关的操作,与BX功能相近(区别:SI和DI不能够分成两个8位寄存器来使用)
- 例:用寄存器
SI
和DI
实现将字符串'welcome to masm!'
复制到它后面的数据区中assume cs:codesg,ds:datasg datasg segment db 'welcome to masm!' db '................' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov di,16 mov cx,8 s: mov ax,[si] mov [di],ax add si,2 add di,2 loop s mov ax,4c00h int 21h codesg ends end start
指针寄存器
- sp 堆栈指针寄存器
存放栈顶的偏移地址 - bp 基址寄存器
段寄存器
- CS:代码段寄存器
就是这个程序中代码开始的地方 - DS:数据段寄存器
程序段前缀(PSP),DOS用来和程序进行通信 - SS:堆栈段寄存器
存放栈顶的段地址 - ES:附加数据段寄存器
CPU从内存中读取数据
- 将
1000:0
中的数据读到al中// 默认段地址是保存在ds里面的 mov bx, 1000H mov ds,bx mov al,[0] // 错误方式 // 8086CPU不支持将数据直接送入段寄存器 mov ds, 1000H
- 累加数据段中的前
3个单元
中的数据mov ax, 123BH mov ds, ax mov al, 0 add al, [0] add al, [1] add al, [2]
- 累加数据段中的前
3个字型数据
mov ax, 123BH mov ds, ax mov ax, 0 add ax, [0] add ax, [2] add ax, [4]
段前缀
- 源程序中的代码:
mov al, [0]
经过编译并连接后:mov al, 0
所以需要显示指明内存单元的段地址ds cs ss es
mov al, ds:[0]
控制寄存器
- IP:指令指针寄存器
标志寄存器
- FLAGS:状态标志寄存器
- PSW:程序状态字
- 字有高八位和低八位,低八位溢出不能进位到高八位
- 直接访问标志寄存器的方法
pushf
:将标志寄存器的值入栈
popf
:将栈中弹出数据,送入标志寄存器
用于寻址的寄存器
寄存器冲突问题的解决
- 子程序标准框架
; 在子程序的开始,将要用到的寄存器中的内容都保存起来,在子程序返回前再恢复 子程序开始: 子程序中使用的寄存器入栈 子程序内容 子程序使用的寄存器出栈 返回 (ret、retf)
- 例:将data段中的字符串转化为大写
assume cs:code data segment db 'word',0 db 'unix',0 db 'wind',0 db 'good',0 data ends code segment start: mov ax,data mov ds,ax mov bx,0 mov cx,4 s: mov si,bx ;si是用来内层循环遍历的 call capital add bx,5 loop s mov ax,4c00h int 21h capital: push cx ;将用到寄存器入栈 push si change: mov cl,si ;将si赋给cx的低8位 mov ch,0 jcxz ok ;如果cx是0的情况下 and byte ptr [si],11011111b ;结果放回到了[si]中 inc si jmp short change ok: pop si ;将用到的寄存器出栈 pop cx ret code ends end start