基于8086cpu的汇编语言学习总结

来源:互联网 发布:贵阳数据博览会 编辑:程序博客网 时间:2024/05/17 05:10

寄存器


  • 通用寄存器:ax、bx、cx、dx。在8086cpu中都是16位的,可拆分成两个8位的来用,如ax可分成al(低8位)、ah(高8位)
  • 段寄存器:cs(code segment)、ds(data segment)、ss(stack segment)、es(external segment)
  • 可用于内存单元寻址的寄存器:bx、bp、di、si,其中bx、di、si段地址默认在ds中,bp的段地址默认在ss中
  • 直接寻址:不使用寄存器。[idata],idata是一个常数,在编写汇编代码时需要添加段前缀,否则编译器会将[idata]解释成一个数据,而不是内存偏移地址。                         如:ds:[idata]表示SA(段地址)=(ds),EA(偏移地址)=idata
  • 寄存器间接寻址:使用一个寄存器。只有bx、di、si、bp这四个寄存器能用于内存单元寻址。前三个的段地址默认在ds中,bp的段地址默认在ss中。如:[bx]表示SA=(ds),EA=(bx),[bp]表示SA=(ss),EA=(bp)
  • 寄存器相对寻址:使用一个寄存器加一个常数。如[bx+idata]表示SA=(ds),EA=(bx)+idata。实际应用:用于数组idata[bx],把idata想象成数组名,c/c++中数组名存的就是数组的起始地址,把bx想象成数组下标
  • 基址变址寻址:使用两个寄存器。如[bx+si]表示SA=(ds),EA=(bx)+(si),bx和si两个都是可变的,可用于二维结构体
  • 相对基址变址寻址:使用两个寄存器加一个常数。如[bx+si+idata]表示SA=(ds),EA=(bx)+(si)+idata。实际应用与二维数组:idata[bx][si]。原理同一维数组类似
  • CS:IP:用于定位指令的内存地址。在8086cpu中CS:IP表示SA=(CS),EA=(IP)。每次执行完一条指令,IP会自动增加,增加的值为所执行完指令的长度
  • SS:SP:用于定位栈空间的内存地址。在8086cpu中SS:SP表示SA=(SS),EA=(SP)。在执行push指令时,SP的值会减少,即栈顶指针向低地址方向移动,执行pop指令时则相反
  • 标志寄存器flag:用来存储相关指令的某些执行结果;用来为CPU执行某些相关指令提供行为依据;用来控制CPU的相关工作方式。
用来存储相关指令的某些执行结果:在8086CPU的指令集中,有的指令是影响标志寄存器的,如add、sub、mul、div、inc、or、and等运算指令;有的指令的执行对标志寄存器没有影响,如push、pop、mov等传送指令。
  • ZF标志,零标志位。它记录相关指令执行后,其结果是否为零。如果是,则为1,否则为0
  • PF标志:奇偶标志位。它记录相关指令执行后,其结果的所有位中1的个数是否为偶数。如果是,则为1,否则为0
  • SF标志,符号标志位。它记录相关指令执行后,其结果是否为负。如果是,则为1,否则为0
  • CF标志,进位标志位。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值或借位值
  • OF标志,溢出标志位。一般情况下,在进行有符号数运算的时候,它记录了运算结果是否发生了溢出。如果发生溢出,OF=1,否则OF=0
  • DF标志,方向标志位。在串处理指令中,控制每次操作后si、di的增减:DF=0,每次操作后si、di递增;DF=1,每次操作后si、di递减
用来为CPU执行某些相关指令提供行为依据:
  • adc指令,带进位加法指令,它利用了CF位上记录的进位值。如adc ax,ax实现的功能是(ax)=(ax)+(ax)+ CF
  • sbb指令,带借位减法指令,它利用了CF位上记录的借位值。如sbb ax,ax实现的功能是(ax)=(ax)-(ax)- CF
  • cmp指令,比较指令,相当于减法指令,不保存运算结果,只改变标志寄存器中相关位的值。cmp指令格式:cmp 操作对象1,操作对象2
对于两个有符号整数a、b,执行cmp a,b指令,通过ZF、SF、OF标志位判断大小:
  • a>b:ZF=0&&(OF=0&&SF=0 || OF=1&&SF=1)
  • a==b:ZF=1
  • a<b:ZF=0&&(OF=0&&SF=1 || OF=1&&SF=0)
对于两个无符号整数a、b,执行cmp a,b指令,通过ZF、CF标志位判断大小:
  • a>b:ZF=0&&CF=0
  • a==b:ZF=1
  • a<b:ZF=0&&CF=1
根据无符号数的比较结果进行转移的条件转移指令:
  • je(jmp equal):等于则转移
  • jne(jmp not equal):不等于则转移
  • jb(jmp below):小于则转移
  • jnb(jmp not below):不小于则转移
  • ja(jmp above):大于则转移
  • jna(jmp not above):不大于则转移
串传送指令:
  • movsb:将ds:si指向的内存单元中的字节送入es:di中,然后根据DF的值增减si、di的值
  • movsw:将ds:si指向的内存单元中的字送入es:di中,然后根据DF的值增减si、di的值
  • cld:设置DF=0;std:设置DF=1
  • rep movsb:根据cx的值,循环执行movsb。相当于 s:movsb;loop s

指令


  • mov:进行赋值操作。注意:段寄存器必须要通过其它寄存器来赋值,不能直接赋值;在赋值时需指定数据大小,用 byte ptr 或word ptr,如 mov byte ptr, [bx]
  • add:加
  • sub:减
  • div:除。用ax和dx两个寄存器来存被除数。在8086cpu中被除数有16位和32位两种情况,如果是16位,直接用ax来存,如果是32位,用ax存低16位,dx存高16位;除数有8位和16位两种情况,如果除数为8位,则al存除法操作的商,ah存余数;如果除数为16位,则ax存除法操作的商,dx存余数
  • mul:乘。两个相乘的数,要么都是8位,要么都是16位。如果都是8位,一个默认放在AL中,结果默认放在AX中;如果都是16位,一个默认放在AX中。结果高位放在DX中,低位放在AX中
  • 数据指定:dd(data double word)、dw(data word)、db(data byte),可用dub重复数据,格式:dd/dw/db 重复的次数 dup(重复的数据内容)
  • 位操作:and,or
  • loop:循环指令。通过命名标识来实现,可以嵌套循环,循环次数存储在cx中
  • 操作符offset,放在标识名的前面,用来获取标识名的段内偏移地址
  • jmp指令是根据位移来进行转移的。cpu在执行jmp指令时,用jmp标号的地址减去jmp指令下一条指令地址,从而得到位移,这样提高灵活性
  • 转移地址在指令中的jmp指令:段内转移:jmp short 标号(8位位移);jmp near ptr标号( 16位位移);段间转移:jmp far ptr 标号,会同时修改CS和IP的值
  • 转移地址在寄存器中的jmp指令:jmp 寄存器表示为IP=(寄存器)
  • 转移地址在内存中的jmp指令:jmp word ptr 内存单元地址(段内转移);jmp dword ptr内存单元地址(段间转移),IP=(内存单元地址),CS=(内存单元地址+2)
  • jcxz指令:条件指令,判断cx是否等于0,如果c等于0,则跳转到标号位置,否则没有任何作用。jcxz标号 相当于 if(cx==0) jmp short 标号
  • ret指令:用栈中的数据修改IP的值,实现段内近转移。相当于pop IP
  • retf指令:用栈中的数据修改IP、CS的值,实现段间转移。相当于pop IP、pop CS
  • call指令:将当前的IP或CS值入栈,然后转移
  • call 标号 相当于 push IP;jmp near ptr 标号
  • call far ptr 标号 相当于 push CS; push IP;jmp far ptr 标号
  • call 16位reg  相当于 push IP; jmp 16位reg
  • call word ptr 内存单元地址 相当于 push IP,jmp word ptr 内存单元地址
  • call dword ptr 内存单元地址 相当于 push CS,push IP,jmp dword ptr 内存单元地址
  • call 和ret指令搭配使用可实现子程序的调用
  • lea指令:把数据的内存地址载入到寄存器中。形如lea  reg,[data] 

中断

中断信息:
  • 除法错误:0
  • 单步执行:1。TF=1
  • 执行into指令:4
  • 执行int指令:int n,n即为中断类型码。
中断过程,由硬件自动完成:
  1. 从中断信息中取得中断类型码:N;
  2. 将标志寄存器的值入栈:pushf;
  3. 设置标志寄存器的第8位TF和第9位IF的值为0:TF=0,IF=0;
  4. CS的内容入栈:push CS;
  5. IP的内容入栈:push IP;
  6. 根据中断类型码,从中断向量表中读取中断处理程序的入口地址,设置CS和IP的值:(IP) = (N*4),(CS) = (N*4+2)。