汇编语言学习笔记--王爽

##第一章 基础知识

1 机器语言是机器指令的集合。机器指令是机器可以正确执行的命令,是一列二进制数字。
2 汇编语言的主题是汇编指令。编译器将汇编指令转换成机器指令。
- 汇编指令:机器码的助记符,有对应机器码;
- 伪指令:无对应机器码,由编译器执行;
- 其他符号:如+等,由编译器识别,无对应机器码。
3 指令和数据是应用上的概念,在内存或磁盘上,都是二进制信息。CPU通过指令流取指令,数据流取数据。 
4 地址总线决定CPU寻址能力;数据总线决定CPU与其他器件进行数据传送时的一次数据传送量;控制总线;
5 CPU通过总线向扩展插槽上的接口卡发送命令,接口卡根据CPU的命令控制外设工作。
6 对CPU来说,系统中所以存储器中的存储单元都处于一个统一的逻辑存储器中,容量受CPU寻址能力限制。这逻辑存储器即内存地址空间。
##第二章 寄存器
1 CPU由运算器、控制器、寄存器等构成,器件靠内部总线相连。
2 为兼容性,8086CPU的AX的低八位AL,高八位是AH寄存器,可作为独立的寄存器使用。
3 汇编指令或寄存器名称不区分大小写。
4 数据传送或运算时,指令的两个操作对象的位数应该是一致的。
5 CPU的16位结构指,运算器一次最多处理16位数据,寄存器最大宽度为16位,寄存器和运算器之间通路16位。
6 物理地址=段地址*16(基础地址)+偏移地址;
    内存没有分段,段的划分来自于CPU。
7 4个段寄存器:CS, DS, SS, ES。 IP为指令指针寄存器,CS:IP即为段地址:偏移地址。
8 mov指令不能修改CS,IP的值;
- jmp 段地址:偏移地址    修改CS, IP的值;是在debug中用的汇编指令,汇编编译器不认识;
- jmp 某一合法寄存器        修改IP值,把合法寄存器的值赋给IP。
9 debug命令: 
- r 查看改变寄存器内容; r ax
- d 查看内存内容;d 段地址:起始偏移地址  结尾偏移地址
- e 改写内存内容;e 起始地址 数据 数据 ...
- e 向内存写入字符,字符串,机器码等;
- U 将内存中内容解释为机器指令和对应汇编指令;
- T 执行CS:IP指向的内存单元处命令;
- A 以汇编指令的形式向内存写入指令;                
##第三章 寄存器
1 字:两个字节;高地址内存单元放字的高位字节;起始地址为N的字单元为N地址字单元。
2 [...] 表示一个内存单元的偏移地址;段地址取DS中数据;
    不支持数据直接送入段寄存器,需用寄存器中转;
    mov bx, 1000H
    mov ds, bx
    mov al, [0]
3 8086CPU入栈和出栈都是以字为单位的。
- 栈顶段地址在SS中,偏移地址在寄存器SP中。SS:SP指向栈顶元素,栈空时,SS:SP指向栈空间最高地址的下一个单元;执行push ax后,SS:SP指向栈中第一个元素;
- 入栈时,栈顶从高地址向低地址方向增长;
- 栈顶超界的问题要自己操心;栈空间是以特殊方式进行访问的内存空间;
4 push pop后可加寄存器,段寄存器,内存单元;本质是内存传送指令;
    push (1)SP减 (2)向SS:SP传送数据
    pop   (1)取SS:SP数据 (2)SP加
5 sub ax,ax机器码为2个字节;mov ax,0 机器码为3个字节。
6 数据段的段地址在DS中,代码段在CS中。
7 T命令在执行修改SS后,下一条指令也被执行。
##第四章 第一个程序
1 伪指令:
(1) XXX segment    ...    XXX ends
成对使用,用来定义一个段,XXX是段名,可存放代码、数据或当做栈空间来使用;
(2) end 汇编程序的结束标记
(3) assume 假设某一段寄存器和程序中的某一个用segments...ends定义的段相关联;
2 程序返回:
mov ax, 4c00H
int 21H
3 DOS有一个程序command.com,命令解释器,就是DOS系统的shell;
- DOS执行1.exe时,是正在运行的command将程序加载入内存;
- 设置CPU的CS:IP指向程序的第一条指令,使程序运行;  
- 程序运行结束后,返回到command中,CPU继续运行command。
4 编译(1.asm)  编译(masm 1.obj)  连接(link 1.exe)  加载(command)  内存中程序  运行(CPU);
5 debug跟踪程序运行 debug 1.exe; command加载debug,debug加载1.exe;CS:IP指向程序的第一条指令;
    单步执行到int 21,需要用P执行;用Q退出debug。
6 cx寄存器是通用寄存器,也是计数寄存器,cx还有一个功能是在程序最初始记录程序代码的字节数;
##第五章 [BX]和loop指令
1 [bx]指偏移地址;
    mov ax, [bx]    (ax)=((ds)*16+(bx))
    mov [bx], ax    ax数据放入(ds)*16+(bx)地址处
    inc bx    bx内容加一
2 通常loop实现循环功能,cx存放循环次数;
    mov cx, 循环次数
s: (标号,代表地址,地址处有指令)
    循环执行的程序段
    loop s
3 汇编源程序中,数字不能以字母开头;
4 debug中 g 0012 使程序执行到CS:IP指向处,IP=0012H;
p 将循环一次执行完   
5 编译器将[0]解释为0,访问[0]写为ds:[0]形式;debug正常;用于显式指明内存单元段地址的ds:  cs:  es:  ss: 被称为段前缀;
6 DOS方式下,0:200~0:2ff空间没有系统或其他程序的数据或代码。
##第六章 包含多个段的程序
1 end 通知编辑器程序结束,还可通知编辑器程序的入口;
可执行文件由描述信息和程序组成。描述信息是编译、连接程序对源程序中的伪指令进行处理得到的消息;
start:   ...   end start指明程序入口;
2 dw定义字型数据
3 程序有多个段,段名代表段地址,偏移地址看他在段中的位置;不允许数据直接送入段寄存器;
4 编程
##第七章 更灵活的定位内存地址的方法
1 and 按位与 相应位置0; or 按位或,相应位置1;
2 [bx+200] 偏移地址为bx中数值加上200,亦写为:200[bx]或[bx].200
3 si和di是和bx功能相近的寄存器,不能分成两个8位寄存器来使用;
[bx+si]表示一个内存单元,偏移地址为(bx)+(si),亦为[bx][si];
[bx+si+idata] 200[bx][si] [bx].200[si] [bx][si].200;
4 一个字母的大小写的区别还在于:0~7位上的第5位如果是1,则为小写,如果为0,则为大写。也就是说不管其第5位如何,将其转为1,并保持其他位的数值不变,都可以得到小写。
##第八章 数据处理的两个基本问题
1 可以用在[]中进行内存单元的寻址:bx,si,di,bp;可以单个出现,或以4种组合出现:bx和si, bx和di, bp和si, bp和di; 其中[bp]的段地址默认在ss中;
2 数据的位置:
- 立即数(idata):直接包含在机器指令中的数据(执行前在CPU的指令缓冲器中);
- 寄存器
- 段地址:偏移地址,数据在内存中;
3 寻址方式
4 指令可以处理word和byte
- 通过寄存器指明处理数据的尺寸;
- 用操作符指明内存单元的长度: word ptr指字单元,byte ptr指字节单元;
- 默认,push [9H] 只对字操作;
5 [bx+si+idata]的寻址方式为结构化数据的处理提供了方便;bx定位整个结构体,idata定位结构体中的某一数据项,si定位数据项中的每个元素;[bx].idata[si]。
6 被除数默认放在AX或AX和DX中,DX存放高16位,AX存放低16位;除数为8位,则被除数为16位;除数为16位,则被除数为32位;
- 除数在一个寄存器或内存单元中;除数为8位,则AL存放商,AH存放余数;除数为16位时,AX放商,DX放余数;
7 db定义字节数据,dw字数据,dd双字,dup进行数据的重复,如db 重复次数 dup (重复的字节型数据);都是由编译器识别处理的;
##第九章 转移指令的原理
1 可以修改IP(段内转移)或同时修改CS和IP的指令(段间转移)统称为转移指令,控制CPU执行内存中某处代码的指令;
短转移IP修改范围为-128~127,用补码表示; 近转移为-32768~32767;
2 操作符offset,取标号的偏移地址;
3 jmp short 标号 (转移到标号处执行指令),指令对应的机器码中,不包含转移的目的地址,而包含转移的位移;短转移;
(IP)=(IP)+8位位移,8位位移=标号处地址-jmp指令后第一个字节的地址,由编译程序编译时算出;
jmp near ptr 标号,(IP)=(IP)+16位位移;
4 jmp far ptr 标号,用标号的段地址和偏移地址修改CS和IP。
5 jmp word ptr 内存单元地址(段内转移)
    jmp dword ptr 内存单元地址 (段间转移),内存单元地址处放着两个字,高地址是段地址,低地址是偏移地址;
6 有条件转移指令 jcxz 标号(如果(cx)=0,转移到标号执行,否则,不做操作),是短转移;
loop为循环指令,所有循环指令都是短转移;
##第十章 CALL和RET指令
1 ret用栈中数据修改IP内容,实现近转移;(IP)=((SS)*16+(SP))  (SP)=(SP)+2
     retf用栈中数据修改CS和IP内容,实现远转移;(IP)=((SS)*16+(SP))  (SP)=(SP)+2 ;(CS)=((SS)*16+(SP))  (SP)=(SP)+2
2 call 标号,相当于 push IP ; jmp near ptr 标号  
- call far ptr 标号,相当于push CS; push IP; jmp far ptr 标号
- call 16位寄存器,相当于 push IP; jmp 16位reg
- call word ptr 内存地址单元,相当于 push IP; jmp word ptr 内存单元地址;
- call dword ptr 内存单元地址,相当于push CS; push IP; jmp dword ptr 内存单元地址;
3 call和ret结合使用实现子程序机制;
4 mul乘法指令,两个相乘的数,都是8位或都是16位;8位时,一个放AL,一个放8位的reg或内存单元中,结果放AX中;16位时,一个放AX,一个放16位的reg或内存单元中,结果高位DX,低位AX中;
5 批量数据传递时,数据放内存,内存的首地址放寄存器中,传给子程序,循环cx的次数是数据的长度;
6 寄存器冲突解决方法:子程序开始时将子程序用到的寄存器入栈,子程序结束后再出栈;
##第十一章 标识寄存器
1 标识寄存器:  
- 存储相关指令的执行结果     
- 为CPU执行相关指令提供行为依据
- 控制CPU的工作方式
2 标识寄存器有16位,存储程序状态字(PSW),是按位起作用的。
3 flag第6位是ZF,零标识位,记录相关指令执行后结果是否为0,若为0则zf=1;有的指令影响flag,如add,sub,mul,div,inc,or,and,大多为运算指令;有的不影响,如mov,pop,push,大多为传送指令;
4 flag第2位是PF,奇偶标志位;所有bit中1的个数为偶数则pf=1; 奇数为pf=0;
5 flag第7位SF,符号标志位;结果为负,sf=1;有符号数计算,记录数据正负,无符号数SF无意义;
6 flag第0位是CF,进位标志位。在无符号数运算时,记录了运算结果的最高有效位向更高位的进位,或从更高位借位;
7 flag第11位是OF位,溢出标志位,发生溢出OF=1;是针对有符号数运算的;
8 adc带进位加法指令,利用CF上记录的进位值;adc ax,bx   (ax)=(ax)+(bx)+CF;
inc 和 loop指令不影响CF位
9 sbb是带借位减法指令,利用CF位上借位值;sbb ax,bx   (ax)=(ax)-(bx)-CF;
10 cmp是比较指令,相当于减法,但不保存结果,通过识别被影响的标志位来得到比较结果;cmp ax,bx   (ax)-(bx)
11 cmp 无符号数, 通过zf和cf判断;有符号数通过sf和of,zf判断,若溢出,则实际结果与逻辑上的真正结果相反;
12 条件转移指令,转移位移是[-128,127];
cmp和je等结合使用实现根据比较结果进行有条件转移;
13 flag第十位是DF,方向标志位,在串处理指令中,控制每次操作后si,di的增减;df=0时,si,di递增;
14 串传送指令movsb相当于执行:
- ((es)*16+(di))=((ds*16+si))
- df=0时,(si)=(si)+1, (di)=(di)+1
    类似的有movsw传送一个字;
    可配合rep使用,rep movsb即为:
    s:movsb
      loop s
    循环实现(cx个字符的传送);
15 cld,将df位置0;std,将df位置1;
16 pushf将标识寄存器的值压栈,popf从栈中弹出数据,送入标志寄存器;为直接访问标识寄存器提供了方法;
17 DEBUG中,对已知标志位值不同时有不同的表示。比如DF=1,表示为DN,DF=0,表示为UP;
##第十二章 内中断
1 中断指CPU不在接着(刚执行完的指令)向下执行,而是转而处理这个特殊信息;产生中断信息:
- 除法错误:中断类型码(字节)0
- 单步执行:1
- 执行into指令:4
- 执行int指令:int n, 中断类型码n
2 中断类型码通过中断向量表找到对应的中断处理程序的入口地址;中断向量就是中断处理程序的入口地址;
中断向量表在内存中保存,0:0~0:03FF的1023个单元放着中断向量表,不能换地;
3 中断类型码找到中断向量,并用他设置CS和IP,CPU硬件完成这个过程被称为中断过程;具体:
- 取得中断类型码
- pushf  恢复CPU现场
- TF=0,IF=0
- push CS
- push IP 返回原来的执行点
- (IP)=(N*4), (CS)=(N*4+2)
4 中断处理程序的常规步骤:
- 保存用到的寄存器
- 处理中断
- 恢复用到的寄存器
- iret指令返回; iret实现 pop IP, pop CS, popf;
5 - * /是编译器识别的运算符号,编译器可用来进行两个常数的减法;
6 CPU提供单步中断功能,为了跟踪程序的执行过程,提供了实现机制;TF=1时,产生单步中断,引发中断过程,执行中短程序前,TF置0,防止死循环;
7 有时CPU执行完当前指令后,即便发生中断,也不会立即响应:sp指令紧接着ss指令执行,中间CPU不会引发中断过程;
##第十三章 int指令
1 int n, 相当于引发一个n号中断;int 和iret结合使用;
2 BIOS主要包含:
- 硬件系统的检测和初始化程序;
- 外部中断和内部中断的中断例程;
- 对硬件设备进行I/O操作的中断例程;
- 其他和硬件系统相关的中断例程;
DOS的中断例程就是操作系统向程序员提供的编程资源;和硬件相关的DOS中断例程,一般都调用了BIOS的中断例程;
3 BIOS和DOS的中断例程安装到内存步骤:
- 开机后,CPU一加电,初始化(CS)=0FFFFH,(IP)=0, 从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,CPU执行该指令后,转而执行BIOS的硬件检测和初始化程序;
- 初始化程序建立BIOS支持的中断向量,中断例程的入口地址登记在中断向量表中,例程是固化在内存的;
- 硬件系统检测和初始化完成后,调用int 19H进行操作系统的引导,将计算机交给操作系统控制
- DOS启动后,还将他提供的中断例程装入内存,建立中断向量;
4 int 10h, 是BIOS提供的中断例程,包含多个和屏幕输出相关的子程序。中断例程内部用传递进来的参数决定执行哪一个子程序。用ah传内部子程序的编号。
5 int 21H, 是DOS提供的中断例程,包好了DOS提供给程序员在编程时调用的子程序;
之前用的解释为:
mov ah,4ch
mov al,0
int 21h
调用的是21h中断例程的4ch号子程序,功能为程序返回,返回值为al值
##第十四章 端口
1 各存储器都和CPU的地址线,数据线,控制线相连,CPU把他们当做一个由若干存储单元组成的逻辑存储器,称为内存地址空间;
2 和CPU通过总线相连的芯片除了各存储器外还有芯片:
- 各接口卡上的接口芯片,控制接口卡工作
- 主板上接口芯片,CPU通过他们对部分外设访问
- 其他芯片
这些芯片都有一组CPU刻读写的寄存器,寄存器物理上可处于不同的芯片中,但(寄存器所在芯片)都和CPU总线相连,CPU通过控制线向寄存器所在芯片发出端口读写命令;
3 CPU把这些寄存器当做端口,统一编址,建立统一的端口地址空间。
CPU可直接读写CPU内部的寄存器,内存单元,端口的数据
4 CPU通过端口地址定位端口,端口地址通过地址总线传送,CPU最多可定位64KB个不同的端口;端口的读写指令只有两个: in,out,其他mov,push,pop等内存读写指令不可用;
5 in(从端口读入),out(往端口写)指令只能用ax或al放从端口读入的数据或发送到端口的数据;16位用ax,8位用al;
- 255~65535内的端口读写时,端口号放dx中;0~255内的端口直接写端口号;
6 CMOS RAM芯片特征:
- 包含一个实时钟和一个有128个存储单元的RAM;
- 芯片靠电池供电,关机后,实时钟正常工作,RAM信息不丢失;
- RAM中内部时钟占0~0DH保存时间信息,其余保存系统配置信息,供系统启动时BIOS程序读取;BIOS也提供了相关程序使我们在开机的时候配置CMOS RAM中的系统信息;
- 有2个端口,70h, 71h;70h为地址端口,存放要访问的CMOS RAM单元的地址; 71h为数据端口,存放从选定的RAM中读取的数据,或要写入的数据;
- CPU对CMOS RAM读写分两步,以读RAM的2号单元为例,先将2送入端口70h,再从71h读出2号单元的内容;
7  shl是逻辑左移指令,功能为:
- 讲一个寄存器或内存单元的数据向左移位;
- 将最后移除的一位写入CF中;
- 最低位用0补充;
- 移动位数大于1时,必须将移动位数放在cl中。类似的,shr是逻辑右移指令
8 CMOS RAM中存放着当前时间:
秒0,分2,时4,日7,月8,年9
数据以BSD码存放,以4位二进制表示十进制,比如0001 0100为14;
BCD码值+30h=十进制数对应的ASCII值;
##第十五章 外中断
1 之前试CPU对指令的执行,除此外,要能对外部设备进行控制,接收输入,向他们输出;IO能力;
2 外设的输入不直接送入内存和CPU,而是送入相关的接口芯片的端口中;CPU向外设输出是先送入端口中,再由芯片转发至外设;CPU通过端口和外设联系;
3 外中断源有两种:可屏蔽中断,不可屏蔽中断。
4 可屏蔽中断,是CPU可不响应的外中断。CPU检测到可屏蔽中断信息后,若IF=1,则CPU在执行完当前指令后响应中断;IF=0时,不响应;
- 中断类型码是通过数据线送入CPU的;
- IF置零是在进入中断处理程序后禁止其他的可屏蔽中断;
- sti, 设IF=1; cli, 设IF=0;
- 几乎所有外设引发的外中断,都是可屏蔽中断;
5 不可屏蔽中断,是CPU必须响应的外中断。中断类型码为2;
6 键盘上的每一个键相当于一个开关,键盘中有一个芯片对键盘上的每一个开关的状态进行扫描;
- 按下一个键,开关接通,该芯片就产生一个扫描码,扫描码说明按键在键盘上的位置,扫描码送入到主板上响应接口芯片的寄存器中,该寄存器的端口地址为60h;通码;
- 松开按下的键也产生一个扫描码,送入60h端口;断码;
- 扫描码为一个字节,通码第七位为0,断码为1,断码=通码+80h;
- 中断类型码为9
7 BIOS提供了int9中断例程,进行基本的键盘输入处理;
- 读出60h端口中的扫描码
- 是字符键的扫描码,则将扫描码和字符码送入内存中的BIOS键盘缓冲区(可存15个键盘输入,一个键盘输入用字存,高位是扫描码,低位字符码);是控制键和切换键,则转换为状态字节,送入内存中存储状态字节的单元,0040:17存键盘状态字节;
- 对键盘系统进行相应控制
8 指令系统总结
数据传送指令,算术运算指令,逻辑指令,转移指令,处理机控制指令,串处理指令;
## 第十六章 直接定址表
1 之前的标号来标记指令、数据、段的起始地址,表示内存单元的地址;还有种标号可以表示内存单元的地址和内存单元的长度;
code segment
a db 1,2,3  没有:,描述地址cs:[0], 表示之后是字节单元;
code ends
2 后面加有:的地址标号,只能在代码段使用;其他段也可以用数据标号描述存储单元的地址和长度。
想在代码段中直接用数据标号访问数据,需要用伪指令assume将标号所在的段和一个段寄存器联系起来,否则编译器编译是不能确定标号所在的段地址在哪个寄存器中。
3 标号可以当做数据来定义;
data segment
  a db 1,2,3
  b dw 1,2
  c dd a b    ;相当于c dw offset a, seg a, offset b, seg b
data ends
seg为取标号的段地址;
4 可以通过依据数据,直接计算出所要找的元素的位置的表,称其为直接定址表;
5 实验16:需要在指令移植的时候在前面指定偏移地址,org 200H;在运行安装程序的时候,table的偏移地址, 在触发7ch中断时仍然生效,导致找不到正确的子程序入口;
##第十七章 使用BIOS进行键盘输入和磁盘读写
1 int 16h功能编号0的作用是从键盘缓冲区读取一个键盘输入,并将其从从缓冲区删除;缓冲区空,则循环等待,直到缓冲区有数据;
2 在int 16h中断例程中,一定有设置IF=1的指令,因为int 16h中断例程在键盘缓冲区中没有数据时,会等待直到键盘缓冲区中有数据为止,因此,int 16h中需要处理int 9h中断,所以一定有设置IF=1的指令。
3 int13h对磁盘进行读写;


posted @ 2018-08-06 17:15  未闻花开  阅读(243)  评论(0编辑  收藏  举报