DOS
DOS环境,需要安装dosemu来模拟DOS环境(Ubuntu的应用商店就有),为了编写汇编,还需要DEBUG、MASM、LINK等汇编语言开发工具。如果你嫌麻烦,推荐使用实验楼已搭好的免费的环境(不是广告,真心推荐)。
在DOS中的操作
在桌面上双击dosemu图标,直接进入DOS。再做如下操作:
1 C:〉D: ——回车后进入D盘2 D:〉CD DOS ——进入DOS子目录3 D:dos〉DIR ——列出目录中的文件4 D:dos〉DEBUG ——进入DEBUG
前置知识
80x86系列微机处理器
学习汇编语言以Intel8086CPU为基础会更容易掌握。
要知道,微型计算机的字长与微处理器的寄存器位数有关。
以Intel 80X86系列微处理器为例,CPU是8086/8088、80286的字长是16位(二进制位bit),那么它们的寄存器的位数一定是16位的;32位字长的微机CPU是80386/80486或者Pentium系列,它们的寄存器的位数则是32位的。
进制
学习汇编语言我们会用到十六进制(H)的数据形式,要使自己尽快习惯用十六进制来思维。在汇编语言中,数值后面分别用字母B、H、D代表二进制(Binary)、十六进制(Hexadecimal)、十进制数(Decimal)(十进制数可以省略D)。
字节、字、双字
字节(Byte):8位二进制数。如00000101B,或表示成05H;10000101B,或表示成85H。
字(Word):16位二进制数,等于2字节。如1100010111010110B,或表示成C5D6H。
双字(Double Word):32位二进制数,又称为双精度数,等于4字节。如23456789H。
原码、反码、补码
在计算机中,对带符号数可用真值和机器数两个概念表示。
真值,就是带有“+”、“-”号的实际数值
机器数,则是把“+”、“-”符号数值化(0、1)后所得到的计算机实际能表示的数。
机器数有三种码表示,分别是原码、反码和补码。汇编语言中,数都是以补码的形式表示的,因此必须掌握数的补码表示和补码的运算。这三种码的定义如下:
原码。原码将最高位作为符号位,正数为0,负数为1,其余7位作为数值位。
反码。正数的反码与正数的原码一样。而求负数的反码时,符号位为1,数值位在原码的基础上求反。
补码。正数的补码与正数的原码一样。求负数的补码时,符号位为1,数值位在原码的基础上求反加1。
[+5]原=[+5]反=[+5]补=00000101B
[-5]原=10000101B
[-5]反=11111010B
[-5]补=11111011B
8086寄存器组
8086寄存器都是16位的寄存器,根据用途可分为4种类型。分别是数据寄存器、地址寄存器、段寄存器和控制寄存器。如图所示:
数据寄存器
数据寄存器中每个寄存器又可以分为2个8位的寄存器。分别为AH、AL,BH、BL,CH、CL,DH、DL。H表示高字节(高8位)寄存器、L表示低字节(低8位)寄存器。例如 用AX寄存器存放一个字1234H,表示为(AX)=1234H,即高字节12放在AH,低字节34放在AL中。
地址寄存器
地址寄存器包括指针和变址寄存器SP、BP、SI、DI四个16位寄存器。顾名思义,它们可用来存放存储器操作数的偏移地址。另外,它们也可以作为通用寄存器用。
段寄存器
8086CPU有4个16位的段寄存器,分别是CS代码段寄存器、DS数据段寄存器、ES附加段寄存器、SS堆栈段寄存器。
代码段——用于存放指令,段地址存放在段寄存器CS。
数据段——用于存放数据,段地址存放在段寄存器DS。
附加段——用于辅助存放数据,段地址存放在段寄存器ES。
堆栈段——是重要的数据结构,可用来保存数据、地址和系统参数,段地址存放在段寄存器SS。
控制寄存器
控制寄存器包括IP和FLAGS(又称为PSW程序状态字)两个16位寄存器。用于控制程序的执行。IP 指令指针寄存器,用来存放代码段中的偏移地址,指出当前正在执行指令的下一条指令所在单元的偏移地址。 FLAGS标志寄存器中的某位代表CPU的1个标志,表示出CPU的某种执行状态。最低位为D0,最高位为D15。8086CPU的标志寄存器共有9个标志,分别为6个条件码标志和3个控制标志。如图:
(1)条件码标志
CF进位标志。当指令执行结果的最高位向前有进位时,CF=1,否则CF=0。
SF符号标志。当指令执行结果的最高位(符号位)为负时,SF=1,否则SF=0。
ZF零标志。当指令执行结果为0时,ZF=1,结果不为0时,ZF=0。
OF溢出标志。当指令执行结果有溢出(超出了数的表示范围)时,OF=1,否则OF=0。
AF辅助进位标志。当指令执行结果的第3位(半字节)向前有进位时,AF=1,否则AF=0。
PF奇偶标志。当指令执行结果中1的个数为偶数个时,PF=1,否则PF=0。
(2)控制标志
DF方向标志。执行串处理指令时,若设置DF=0,存储单元的地址寄存器的值自动增加,若设置DF=1,存储单元的地址寄存器的值自动减小。
IF中断标志。设置IF=1,允许CPU响应可屏蔽中断,IF=0则不响应。
TF陷阱标志。在DEBUG调试时,TF=1,采用单步执行方式,即进入陷阱;TF=0,正常执行程序。
例: 两个二进制数相加运算,有关标志位自动发生变化。
根据计算结果可知CPU会自动地把标志位设为:CF=0,SF=1,ZF=0,OF=0,PF=0,即无进位,结果为负数,结果不为0,没有溢出,奇数个1。
对溢出的判断:可以从简单的角度理解,因为进行运算的二进制数是补码,可看出本题是一个负数和一个正数相加,结果为负数,不溢出。若两个正数相加,结果为负数,或者两个负数相加,结果为正数,那都是溢出了,说明8位补码已经表示不了该结果。
小贴士DEBUG下的标志位表示:
在DEBUG调试环境下以字母缩写的形式表示各个标志位的状态。进入DEBUG后,用R命令查看寄存器状态时,可以看到除了陷阱标志以外的标志位的状态。如表所示:
内存
对存储单元的标识可以用物理地址或逻辑地址表示。
物理地址
物理地址是内存单元的真实地址,存储单元的物理地址是唯一的。
Intel8086CPU有20根地址线,因此其存储空间可达2的20次方=1M个字节单元(1MB)。地址都是从0开始的,在20位地址线的存储空间中采用十六进制表示的物理地址范围是00000H~FFFFFH。
逻辑地址
逻辑地址是用户编程时使用的地址,分为段地址和偏移地址两部分。在8086汇编语言中,把内存地址空间划分为若干逻辑段,每段由一些存储单元构成,每段最大为65536个字节单元(0号单元~65535号单元0000H~FFFFH)。用段地址指出是哪一段,偏移地址标明是该段中的哪个单元。段地址和偏移地址都是16位二进制数。逻辑地址的形式:段地址:偏移地址
每段的长度可以不一样,如0号段从0号单元到0FH号单元共16个字节单元,1号段从0号单元到0139H号单元共314个字节单元。。用段地址表示段号,偏移地址代表每一段中的单元号,比如0000:0002H代表0号段的2号单元,0001:0002H代表1号段的2号单元
转换
用户编程时采用的逻辑地址在CPU执行程序时都要转换成实际的物理地址,这个转换过程是由CPU中的地址加法器自动完成的。
转换时先将16位的段地址左移4位,相当于乘以16或十六进制的10H,再和偏移地址相加。转换公式为:物理地址=段地址×10H+偏移地址
例: 若某单元的逻辑地址为0001:0002H,其物理地址=0001H×10H+0002H=00012H
另一单元的逻辑地址为3020:055AH,其物理地址=3020H×10H+055AH=3075AH
存储单元
存储单元中的数据称为存储单元内容,一个实际的存储单元只能存放一个字节(8位二进制)的数据。
存储单元的地址和内容的表示形式为用括号将地址括起来以代表单元的内容。如(3075AH)=12H,表示3075AH号单元中的内容是12H,称为字节单元;
若(37692H)=5678H,表示37692H单元和37693H单元一起存放5678H,该单元是字单元。字单元在存储的时候,高字节放在高地址单元,低字节放在低地址单元,即56H放在37693H单元,78H放在37692H单元。如图: