清华大学《汇编语言》(王爽)读书笔记第一章基础知识◎汇编语言由3类指令组成汇编指令:机器码的助记符,有对应机器码。
伪指令:没有对应机器码,由编译器执行,计算机并不执行其他符号:如+-*/,由编译器识别,没有对应机器码◎一个CPU有n根地址线,则可以所这个CPU的地址线宽度为n,这样的CPU最多可以寻找2的n 次方个内存单元。
◎ 1K=2^10B 1M=2^20B 1G=2^30B◎8086 CPU地址总线宽度为20,寻址范围为00000~FFFFF00000~9FFFF 主存储器地址空间(RAM)A0000~BFFFF 显存地址空间C0000~FFFFF 各类ROM地址空间第二章寄存器(CPU工作原理)◎16位结构描述了一个CPU具有下面几个方面的结构特性运算器一次最多可以处理16位的数据寄存器的最大宽度为16位寄存器和运算器之间的通路为16位◎8086有20位地址总线,可以传送20位地址,达到1M的寻址能力。
采用在内部用两个16位地址合成的方法来形成一个20位的物理地址◎物理地址 = 段地址 × 16 + 偏移地址◎在编程是可以根据需要,将若干地址连续的内存单元看作一个段,用段地址×16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
段地址×16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址位16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB◎8086有四个段寄存器 CS、DS、SS、ES◎CS为代码段寄存器,IP为指令指针寄存器。
任意时刻,设CS中内容为M、IP中内容为N,8086CPU从内存M×16+N读取一条指令执行◎不能用mov修改CS、IP,因为8086CPU没有提供这样功能,可用指令JMP 段地址:偏移地址。
JMP 2AE3:3 JMP AX 修改IP第三章寄存器(内存访问)◎DS数据段寄存器。
不能将数据直接送入段寄存器,所以『MOV DS, 1』不正确◎字在存储时要两个连续的内存单元,低位在低地址,高位在高地址◎[address]表示一个偏移地址为address的内存单元◎SS:SP指向栈顶元素◎PUSH AX:(1)SP = SP - 2;(2)AX送入SS:SP◎POP AX:(1)SS:SP送入AX;(2)SP = SP + 2◎PUSH/POP 寄存器PUSH/POP 段寄存器PUSH/POP 内存单元第四章第1个程序◎可执行文件包含两部分:程序和数据,相关的描述信息◎程序加载后, ds中存放这程序所在内存区的段地址,这个内存区的偏移地址为0,策程序所在的内存区的地址为ds:0;这个内存区的前256个字节中存放的是PSP,dos用来和程序进行通信。
从256字节处向后的空间存放的是程序。
第五章 [BX]和loop指令◎[BX]表示一个内存单元,它的段地址在ds中,偏移地址在bx中。
MOV AX,[BX] MOV AL,[BX]MOV [BX],AX◎loop要进行两步操作,CX=CX-1;判断cx中值,不为零则转至标号处执行程序,为零则向下执行。
◎masm将指令 mov ax,[0] 当作 mov ax,0 处理解决方法可以为 mov bx,0 使用寄存器mov ax,[bx]或 mov ax,ds:[0] 直接给出段地址所在的段寄存器◎loop中不可使用 mov [cx],cx第六章包含多个段的程序◎dw 定义字型数据◎end 标号定义程序入口点◎定义多个段,同定义代码段相同。
定义仅仅是为了程序阅读方便◎assume cs:code,ds:data,ss:stack是伪指令,将定义的具有一定用途的段和相关的寄存器联系起来◎对于段,如果数据占N个字节,则程序加载后实际占有空间为:(N/16+1)*16,N的16整数第七章更灵活的定位内存地址的方法◎and 按位与 and al, 0EFh◎or 按位或 or al, 20h◎字母大小写转换:大写(xx0x xxxx) and al, 0EFh小写(xx1x xxxx) or al, 20h◎mov ax,[200+bx] == mov ax,[bx+200] == mov ax,200[bx] == mov ax,[bx].200 段地址为ds,偏移地址为bx+200◎si和di示8086CPU中和bx功能相近的寄存器,si和di不能分成两个8位寄存器来使用◎一般来说,在需要暂存数据的时候,都应该使用栈第八章数据处理的两个基本问题◎bx,si,di,bp1。
在8086CPU中,只有这4个寄存器可以用在[...]中来进行内存单元的寻址正确:mov ax,[bx] | mov ax,[bp]错误:mov ax,[cx] | mov ax,[dx] | mov ax,[ax] | mov ax,[ds]2。
在[...]中,这4个寄存器可以单个出现,或只能以四种组合出现:bx和si、bx和di、bp和si、bp和di错误:mov ax,[bx+bp] | mov ax,[si+di]3。
只要在[...]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中mov ax,[bp] ax=ss*16+bp(取地址值)◎在没有寄存器名存在的情况下,用操作符 X ptr 指明内存单元的长度,X在汇编指令中可以位word 或byte:mov word ptr ds:[0],1 | add word ptr [bx],2 | inc byte ptr ds:[2]◎div,除法指令 div 除数除数 8位 16位被除数 AX DX->高16位 AX->低16位商 AL AX余数 AH DX◎dd 伪指令,定义双字dword◎dup 伪指令,用来进行数据的重复db 3 dup (0) == db 0,0,0db 3 dup (0,1,2) == db 0,1,2,0,1,2,0,1,2db 3 dup ('ab','CD') == db 'abCDabCDabCD'第九章转移指令的原理◎可以修改ip,或同时修改cs和ip的指令统称为转移指令◎8086CPU的转移行为有一下几类:只修改ip时,称为段内转移,如jmp ax同时修改cs和ip时,称为段间转移,如jmp es:[dx]由于转移指令对ip的修改范围不同,段内转移又分为:短转移和近转移短转移ip的修改范围为 -128~127近转移ip的修改范围为 -32768~327678086CPU的转移指令分为以下几类:无条件转移指令(如jmp)条件转移指令循环指令(如loop)过程中断◎offset 取得标号的偏移地址◎jmp short 标号实现段内短转移,对ip的修改范围为 -128~127 对应机器码中包含转移的位移 EB 地址◎jmp near ptr 标号实现段内近转移,对ip的修改范围为 -32768~32767 对应机器码包含转移的位移◎jmp far ptr 标号实现段间转移对应机器码中高地址为段地址,低地址为偏移地址 EA偏移地址段地址◎jmp word ptr 内存单元地址(段内转移)◎jmp dword ptr 内存单元地址(段间转移)高地址存放目的段地址,低地址存放目的偏移地址◎jcxz 标号 cx为0时跳转所有有条件跳转指令都是短转移,对ip的修改范围都为 -128~127◎loop 标号所有循环指令都是短转移,对ip修改范围都为 -128~127◎80×25彩色字符显示模式显示缓冲区结构:内存地址空间中,B8000h~BFFFFFh共32KB的空间,为80×25彩色显示缓冲区。
向这个地址写入数据,写入的内容将立即出现在显示器上。
在80×25彩色字符模式下,显示器可以显示25行,每行80个字符,每个字符可以有256种属性。
一个字符在缓冲区占两个字节,一屏内容共占4000个字节。
显示缓冲区分8页,每页4KB,显示器可以显示任意一页的内容,一般显示第0页,即B8000h~B8F9Fh。
在一行中,一个字符占两个字节的存储空间,低位字节存储字符的ASCII码,高位字节存储字符的属性,一行80字符,占160字节属性字节的格式:7 6 5 4 3 2 1 0BL(闪烁) RGB(背景) I RGB(前景)显示在 M行 N列的字符为 B800:[160*M + 2*N]第十章 call和ret指令◎ret用栈中数据修改ip,实现近转移(ip) = ((ss) * 16 + (sp))(sp) = (sp) + 2相当于:POP ip◎retf用栈中数据修改cs和ip,实现远转移(ip) = ((ss) * 16 + (sp))(sp) = (sp) + 2(cs) = ((ss) * 16 + (sp))(sp) = (sp) + 2相当于:POP ipPOP cs◎call指令,call指令不能实现短转移,实现转移的方法和假名牌指令原理相同1。
call 标号,段内转移机器指令中没有转移的目的地址,而是相对于当前ip的转移位移(补码),相当于 1.push ip 2.jmp near ptr 标号2。
call far ptr 标号,段间转移机器指令中包含转移目的地址,相当于 1.push cs 2.push ip 3.jmp far ptr 标号3。
call 16位寄存器相当于 1.push ip 2.jmp 16位寄存器,机器指令不包含目的地址注意:1.push ip ip先变成call后第一个字节的偏移地址,然后入栈4。
call word ptr 内存地址相当于 1.push ip 2.jmp word ptr 内存地址5。
call dword ptr 内存地址相当于 1.push cs 2.push ip 3.jmp dword ptr 内存地址注意:2.push ip ip先变成call后第一个字节的偏移地址,然后入栈◎mul 指令,乘法 a × ba 8位 16位b AL AX结果 AX 高位DX,低位AX第十一章标志寄存器◎ 11 10 9 8 7 6 4 2 0OF DF IF TF SF ZF AF PF CF◎ZF 零标志位,如果运算结果为零,则 ZF=1◎PF 奇偶标志位,相关指令执行后,1 的个数为偶数 PF=1◎SF 符号标志位,执行后,计算结果为负 SF=1◎CF 进位标志位,无符号加减发生最高有效位之外的进、接位时 CF=1◎OF 溢出标志位,有符号运算发生溢出时 CF=1◎adc 带进位加法,adc ax,bx == (ax)=(ax)+(bx)+CF◎sbb 带借位减法,sbb ax,bx == (ax)=(ax)-(bx)-CF◎cmp 比较指令,相当于减法,但是不保存结果,只影响标志寄存器cmp ax,bx无符号比较时:ax==bx, ZF=1ax<>bx, ZF=0ax< bx, CF=1ax> bx, CF=0 and ZF=0ax<=bx, CF=1 or ZF=1ax>=bx, CF=0有符号比较时(反向说明)cmp ah,bh:SF=0 and OF=0, ah>=bhSF=0 and OF=1, ah< bhSF=1 and OF=0, ah< bhSF=1 and OF=1, ah> bh◎无符号比较跳转指令je, ZF=1jne, ZF=0jb, CF=1jnb, CF=0ja, CF=0 and ZF=0jna, CF=1 or ZF=1◎DF 方向标志位,在串处理指令中,控制每次操作后si di的增减,DF=1 操作后si di递减使用cld,std设置: cld, DF=0. std, DF=1◎movsb 将ds:si内存单元字节送入es:di相当于:mov es:[di], byte ptr ds:[si] ;非8086指令DF=0: inc si, inc diDF=1: dec si, dec di类似的还有movsw,传送一个字一般使用格式为 rep movsb相当于 s:movsb, loop s,所以要在之前设置cx◎pushf 将标志寄存器值入栈, popf 将标志寄存器值出栈◎标志寄存器在debug中的表示0 OV DN NG ZR PE CY1 NV UP PL NZ PO NCOF DF XX SF ZF XX PF CF第十二章内中断◎中断类型码:除法错误:0单步执行:1int0指令:4int n:n◎中断向量表 0000:0000~0000:03E8,1000个单元,N号中断偏移地址为4N,段地址为4N+2,高地址为段地址,低地址为偏移地址◎中断处理过程:1.取得中断类型码 N2.pushf3.TF=0, IF=04.push CS5.push IP6.ip=4N, cs=4N+2◎中断处理程序的编写和子程序类似,常规步骤为:1.保存用到的寄存器2.处理中断3.恢复用到的寄存器4.用iret返回(iret = pop ip, pop cs, popf)第十三章 int指令◎10中断mov ah, 2 ;置光标,2号子例程为设置光标位置mov bh, 0 ;第0页mov dh, 5 ;行号mov dl, 12 ;列号int 10h-----------mov ah, 9 ;9号子例程为在光标位置显示字符mov al, 'a';字符mov bl, 7 ;颜色属性mov bh, 0 ;第0页mov cx, 3 ;字符重复个数int 10h第十四章端口◎端口的读写只能用in(读入)和out(写入)◎在in和out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据。