《汇编语言》的1-8章已经学习完毕,这篇笔记是对前面所学的总结,想到哪些知识点就写下来(以下内容都是以8086CPU为基础)。
汇编语言是直接对硬件编程的语言,由机器语言发展而来,采用自然语言的形式书写指令并通过编译器编译为机器语言后由计算机执行。汇编程序主要由两部分组成:指令和数据。
1.mov指令:数据传输命令, 和高级语言的赋值语句非常想像,mov指令有以下几种形式。
1.1 mov 寄存器,数据:将数据存储到寄存器中。比如:mov ax,1,指令执行后(ax)=1.
1.1.1 寄存器:cpu中的信息存储部件,汇编语言对cpu的控制是通过改变寄存器内的值来实现的,8086寄存器分为通用寄存器、段寄存器和控制寄存器。
1.1.1.1 通用寄存器:ax,bx,cx,dx,si,di,sp,bp.
ax,bx,cx,dx称为数据寄存器,ax(accumulator)累加寄存器,bx(base)基地址寄存器,cx(count)计数寄存器,dx(data)数据寄存器。
sp,bp称为指针寄存器,sp(stack pointer)堆栈指针寄存器,bp(base poionter)基指针寄存器。
si,di称为变址寄存器,si(source index)源变址寄存器,di(destination index)目标变址寄存器。
1.1.1.2 段寄存器:cs(code segment)代码段寄存器,ds(data segment)数据段寄存器,ss(stack segment)堆栈段寄存器,es(extra segment)附加段寄存器。
1.1.1.3 控制寄存器:ip(instruction pointer)指令指针寄存器。
1.2 mov 寄存器,寄存器:寄存器之间数据的传输。比如:mov ax,bx,指令执行后(bx)=(ax).
1.3 mov 寄存器,内存单元:将内存单元中的数据传输至寄存器中。比如:mov ax,[0].
1.3.1 8086CPU是20位的地址总线,而寄存器都是16位,所以地址的表示方式都以段地址:偏移地址进行。
1.3.2 段地址存储在段寄存器中,[0]在默认情况下表示的地址是ds:0,也可以在mov指令中显示的指定段寄存器,例如mov ax,es:[0],还可以将偏移地址储存在通用寄存器中,mov ax,ds:[bx];mov ax,[bp];mov ax,es:[si]都是合法的。
1.4 mov 内存单元,寄存器:将寄存器中的数据传输至寄存器。比如:mov [0],ax.
1.5 mov 段寄存器,寄存器:将寄存器中的数据传输至段寄存器。比如:mov ds,ax.因8086不容许直接对段寄存器进行数据传输操作像mov ds,01h这种形式的指令是错误的,采用mov ds,ax的形式。
1.6 mov 寄存器,段寄存器:将段寄存器中的数据传输至寄存器。比如:mov ax,ds,用于多段的程序。
2.add指令:累加指令,add ax,1表示将ax中的值加1结果储存在ax中,用高级语言表示(ax)+=1,add指令形式与mov相同。
3.sub指令:减法指令,sub ax,bx表示将将bx中的值减去ax中的值结果储存在ax中,用高级语言表示(ax)=(bx)-(ax),sub指令形式与mov相同,需注意sub 内存单元,段寄存器的形式是错误的。
4.inc指令:自增1,inc bx等同于add bx,1.
5.div指令:除法指令,使用除法的时候有两种情况,即除数可以是8位或16位。
5.1 除数是16位,这种情况下被除数一定是32位的,因为ax是16位寄存器,放不下32位的被除数,还需要使用另一个16位寄存器dx。dx存放被除数的高16位,ax存放被除数的低16位,ax中会保存除法操作的商,dx保存除法操作的余数。
5.2 除数是8位,被除数存储在ax中,al中会保存除法操作的商,ah保存除法操作的余数。
6.push指令:入栈指令,push ax表示将ax中的数据压入栈中。
6.1 栈是一段人为划分的内存空间,ss:sp指向栈顶,执行push指令,sp=sp-2,执行pop指令sp=sp+2(入栈、出栈的都是字型数据2B)。当栈为空时,ss:sp指向栈底部字单元地址+1的地方,假设10000H~1000FH这段空间为栈空间,则ss=1000hH,sp=0010H.
6.2 8086CPU没有判断栈顶是否超界的机制,这需要我们在编程中规划好。
7.pop指令,出栈指令,pop ax表示将当前栈顶元素出栈,存入ax中,同时sp=sp+2.
8.loop指令,循环指令,loop s表示循环执行标号s开始的代码,执行loop需要两个条件即cx>0和标号。
1 assume cs:codesg 2 3 codesg segment 4 5 mov ax,1 6 mov cx,3 7 8 s: add ax,1 9 loop s 10 11 mov ax,4c00h 12 int 21h 13 14 codesg ends 15 16 end
8.1 标号是循环从何处开始的标志,上面代码中,标号s在指令add ax,1处,则满足循环条件时,loop s命令循环执行add ax,1这句指令。
8.2 上文中已经指出cx是计数寄存器,在这里计的就是循环次数,执行loop指令时先将cx减1,然后判断cx是否=0,若不等于则执行标号处开始的指令,若等于零则执行loop下方指令,上文代码中add ax,1执行3次。
1.assume:将段与某个段寄存器关联起来。
2.segment...ends:定义一个段,segment说明段的开始,ends说明结束,指令、数据、栈等可以单独定义为一个或多个段。
3.end:说明一个程序的结束,可以和start配合使用,start表示指令开始的地方。
4.db:db即define byte定义字节型数据, db 'A'表示定义1个字节型数据,大小为1B。
5.dw:dw即define word定义字型数据,dw 0123h表示定义一个字型数据,大小为2B。
6.dd: dd即double word定义双字型数据,dd 0123h表示定义一个双字型数据,大小为4B。
1.dup:表示定义重复的数据,和db、dw、dd配合使用,db 3 dup('A')相当于db 'AAA'。
表示方式:多用十六进制表示,4个二进制数正好可以表示0-15,即十六进制的0-F,那么一个内存单元可以用2个十六进制数表示,A9H相比10101001B和169D更利于理解和计算。
存储位置:汇编中的数据主要存储在3个地方
1.指令缓冲器主要用来存储常量,mov ax,1中的1就是存储在指令缓冲器中。
2.寄存器,以寄存器名称的形式给出,mov ax,bx的形式。
3.内存单元,以段地址:偏移地址的形式给出,mov ax,ds:[bx]。