机器语言与机器指令
- 机器语言是机器指令的集合。
- 机器指令是一台机器可以正确执行的命令。
汇编语言与汇编指令
- 汇编语言的主体是汇编指令。
- 汇编指令和机器指令的差别在于指令的表示方法上
- 汇编指令是机器指令便于记忆的书写格式色
- 汇编指令是机器指令的助记符。
例如
机器指令:1000100111011000
操作:将寄存器BX的内容送到AX中
汇编指令:MOV AX BX
内存的读写和地址空间
- cpu对存储器的读写
- CPU要想进行数据的读写,必须和外部器件进行三类信息的交互∶
- 存储单元的地址(地址信息)
- 器件的选择,读或写命令(控制信息)
- 读或写的数据(数据信息)
内存地址空间
-
什么是内存地址空间
-
CPU地址总线宽度为N,寻址空间为2的N次方字节
-
8086CPU的地址总线宽度为20,那么可以寻址1MB个内存单元,其内存地址空间为1MB。
-
将各类存储器看作一个逻辑存储器―-统一编址
-
所有的物理存储器被看作一个由若干存储单元组成的逻辑存储器。
-
每个物理存储器在这个逻辑存储器中占有一个地址段,即一段地址空间。
cpu的组成
- 运算器进行信息处理
- 寄存器进行信息存储
- 控制器协调各种器件进行工作
- 内部总线实现cpu内各个器件之间的联系
- 寄存器是cpu的内部信息存储单元
- 8086CPU有14个寄存器︰
- 通用寄存器:AX、BX、CX、DX
- 变址寄存器:SI、Dl
- 指针寄存器:SP、BP
- 指令指针寄存器:IP
- 心段寄存器:CS、sS、DS、ES个
- 标志寄存器:PSw
- 一个16位寄存器存储一个16位的数据
- 最大值?
- 2的16次方 -1
- 8086cpu 通用寄存器可分为两个独立的8位寄存器使用
- 细化AX 可分为AH和AL(高八位,低八位)
- 8086是 16位的cpu -- 8086的字长位16位(bit)
- 个字word)可以存在一个16位寄存器中
- 这个字的高位字节存在这个寄存器的高8位寄存器
- 这个字的低位字节存在这个寄存器的低8位寄存器
MOVE和ADD指令
- 溢出在汇编语言中是存在的
- 低八位相加的溢出不能进到高位,进位会被丢掉!!!
- 高位相加的溢出同样不能进位
确定物理地址的方法
- 物理地址
- CPU访问内存单元时要给出内存单元的地址。
- 所有的内存单元构成的存储空间是一个一维的线性空间。
- 每一个内存单元在这个空间中都有唯一的地址,这个唯-的地址称为物理地址。
- 8086有20位地址总线,可传送20位地址,寻址能力为1M。
- 8086是16位结构的CPU
- 运算器一次最多可以处理16位的数据,寄存器的最大宽度为16位。
- 在8086内部处理的、传输、暂存的地址也是16位,寻址能力也只有64KB !
- 8086如何处理在寻址空间上的这个矛盾?
- 8086CPU的解决方法
- 用两个16位地址(段地址、偏移地址)合成一个20位的物理地址。
- 地址加法器合成物理地址的方法,物理地址 = 段地址×16+偏移地址
- 段地址×16+偏移地址的本质含义
- CPu在访问内存时,用一个基础地址(段地址×16)和一个相对于基础地址的偏移地址相加,给出内存单元的20位的物理地址。
内存的分段表示法
- 8086CPU用”(段地址×16 )+偏移地址=物理地址”的方式给出内存单元的物理地址。
内存并没有分段,段的划分来自于CPU!!!
用不同的段地址和偏移地址形成同一个物理地址
- 段地址x16必然是16的倍数,所以一个段的起始地址也一定是16的倍数。偏移地址为16位,16位地址的寻址能力为64k,所以一个段的长度最大为64k。
- 段地址很重要!一一用专门的寄存器存放段地址。
- 四个段寄存器∶
- cs-代码段寄存器
- Ds-数据段寄存器
- SS-栈段寄存器
- ES -附加段寄存器
CS、IP与代码段
- cs :代码段寄存器
- IP:指令指针寄存器
- CS:IP :CPU将内存中CS:lP指向的内容当作指令执行。
- 8086工作过程的简要描述:
- 从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
- lP =IP+所读取指令的长度,从而指向下一条指令;
- 执行指令。转到步骤
- 重复这个过程。
跳转指令jmp
-
跳转指令的应用:修改cs、ip的指令
-
事实∶执行何处的指令,取决于CS:IP
-
应用:可以通过改变CS、IP中的内容,来控制CPU要执行的目标指令
-
同时修改cs、ip的内容
-
jmp 段地址:偏移地址
- jmp 2AE3:3
- jmp 3:0B16
- 用指令中给出的段地址修改cs、偏移地址修改ip
-
仅修改ip的内容
- jmp 某一合法寄存器
- jmp ax
- jmp bx
- debug 跟踪调试
内存中字的存储
-
8086cpu,16位作为一个字
-
16位的字存储在一个16位的寄存器中,如何存储?
- 高8位放高字节,低8位放低字节
-
16位的字在内存中需要2个连续字节存储,怎么存放?
- 低位字节存在低地址单元,高位字节存在高地址单元
- 例:20000D ( 4E20H )存放o、1两个单元,18D( 0012H)存放在2、3两个单元
- 先读高地址,再读低地址单元
- 字单元
- 由两个地址连续的内存单元组成,存放一个字型数据(16位)
- 原理:在一个字单元中,低地址单元存放低位字节,高地址单元存放高位字节
用DS和【address】实现传送
- 要解决的问题:CPU从内存单元中要读取数据
- CPU要读取一个内存单元的时候,必须先给出这个内存单元的地址;
- 在8086PC中,内存地址由段地址和偏移地址组成(段地址:偏移地址)
- 解决方法:DS和【address】配合
- 用Ds寄存器存放要访问的数据的段地址
- 偏移地址用[...]形式直接给出
DS和数据段
对内存单元中数据的访问
- 对于8086Pc机,可以根据需要将一组内存单元定义为一个段。
- 物理地址=段地址×16+偏移地址
- 将一组长度为N (N<64K )、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间,从而定义了一个数据段。
- 用mov指令操作数据
- 加法add和减法sub指令
栈及栈操作的实现
- CPU提供的栈机制
- 现今的CPU中都有栈的设计。
- 8086CPU提供相关的指令,支持用栈的方式访问内存空间。
- 基于8086CPU的编程,可以将一段内存当作栈来使用。
段总结
用汇编语言写的源程序
- 汇编程序:包含汇编指令和伪指令的文本。
- 通过编译、链接变为机器码
- 单独编写成源文件后再编译为可执行文件的程序
[...]的规定与(...)的约定
- [...] -- (汇编语法规定)表示一个内存单元
loop指令
- 功能:实现循环(计数型循环)
- 指令的格式:loop 标号
- cx = cx -1
- 判断cx中的值
- 不为零则转至标号处执行程序
- 如果为零则向下执行
- cx中要存放循环的次数,因为cx影响着loop指令的执行结果。
- 要定义一个标号
- 编程计算2的n次方
assume cs:code
code segment
mov ax,2
mov cx,11
s:add ax,ax
loop s ;连续执行11此s
mov ax , 4c00h
int 21h
code ends
end
- 计算ffff:0006字节单元中的数乘以3,结果存储在dx中,先将内存中的数据取出 连加三次即乘以三
- 在汇编源程序中,数据不能以字母开头,要在ffff前面加零
assume cs:code
code segment
mov ax,0ffffh
mov ds,ax
mov bx,6
mov al,[bx]
mov ah,0
mov dx,0
mov cx,3
s:add dx,ax
loop s
mov ax ,4c00h
int 21h
code ends
end
段前缀的使用
- 问题:编译后把偏移地址当成常数来使用
- 解决:在偏移地址前面加上ds:[0]
处理字符问题
- 汇编语言中,用 '字符' 的方式指明数据是以字符的形式给出的,编译器将把它们转化为ASCII码
寻址方式
- [bx+idata]的含义
大小写转换
SI和DI寄存器
- SI和DI常执行与地址有关的操作
- SI和DI是8086cpu中和BX功能相近的寄存器
- 区别:SI和DI不能够分成两个8位寄存器来使用
- 区别:SI和DI不能够分成两个8位寄存器来使用
- 用寄存器SlI和DI实现将字符串‘welcome tomasm!’复制到它后面的数据区中。
[bx+si]和[bx+di]方式寻址
- [bx+si]表示一个内存单元
- 偏移地址为(bx)+(si)即bx中的数值加上si中的数值
- 基址 变址寻址方式
- 内存中的数据 2000:1000 BE 00 06 00 00 00...
- 程序执行后,ax、bx、cx、的内容
[bx+si+idata] 和 [bx+di+idata]方式指定地址
- 对内存的寻址方式
- 用于内存寻址的寄存器
- bx,bp区别:
- bx默认指ds段
- bp默认指ss段
汇编语言中数据位置表达
指令要处理的数据有多长
div指令(除法)
- 切记提前在默认的寄存器中设置好被除数且默认寄存器不作别的用处。
用dup设置内存空间
“转移”综述
操作符 offset
- 用操作符offset取得标号的偏移地址
jmp指令--无条件转移
- jmp指令:依据位移进行转移
- 两种段内转移