汇编语言-复习笔记

2019.6.10

Posted by Kingtous on June 10, 2019

满足CPU中断的条件

  • CPU执行完当前的指令周期
  • 当前运行的为非中断程序或者是优先级较低的中断服务程序
  • 采样到有效的中断请求信号
  • 如果是可屏蔽中断请求INTR,检查中断允许标志是否为1,即中断开放

CPU不响应的情况

  • 执行STI时
  • 执行IRET
  • 向SS中传送数据时

中断优先级

(从高到低)

  • 内中断
  • 非屏蔽中断
  • 可屏蔽中断
  • 单步中断

CF与OF的联系

(1)、8H+8H: 对于signed:(8)+(8)=16,没超过[-128,127]的范围,OF为0 对于unsigned:(8)+(8)=16,没超过[0,255]的范围,CF为0 (2)、80H+81H: 对于signed:(-128)+(-127)=-255,超过[-128,127]的范围,OF为1 对于unsigned:(128)+(129)=257,超过[0,255]的范围,CF为1 (3)、FCH+05H: 对于signed:(-4)+(5)=1,没有超过[-128,127]的范围,OF为0 对于unsigned:(252)+(5)=257,超过[0,255]的范围,CF为1 (4)、7FH+2H: 对于signed:(127)+(2)=129,超过[-128,127]的范围,OF为1

例:

mov ax,85

mov bx,-45

add ax,bx

答案:CF=1 OF=0

解释:

当为无符号数时,溢出(-45的补码前面是FF),所以CF=1

当为有符号数时,数值没有超过范围,所以OF=0

宏和子程序

相同之处:

  • 都可以定义为一段功能程序,被其他程序调用

不同之处:

  • 宏可利用哑元和实元进行参数传递
  • 实元还可以是指令的操作码或操作码的一部分,在编译汇编的过程中指令可以改变
  • 宏调用的工作方式和子程序调用的工作方式是完全不同的

简述操作系统对可执行程序的加载和执行过程

  • 将程序调入内存
  • 建立256字节的PSP区
  • 在PSP分区后建立代码段
  • 如果有自定义数据段时,则在PSP和代码段中预留数据段空间
  • 定义堆栈段,SS,SP
  • 将CS,IP改为程序入口
  • 将控制权转交给程序,程序执行

SAL和SHL的区别

SHL,SAL分别是逻辑左移和算术左移,运行结果是一样的,都是数据往左移动,然后在右边补零; SHR是逻辑右移,数据往右移动,在左边补零。如:1000 0000->0010 0000(逻辑右移两位) SAR是算术右移,比较特殊。他的最高位一直是不变的。如1000 0000算术右移7位后就成了1111 1111.

串处理

  • 串传送

    • movs es:[di],ds:[si]
  • 串比较

    • cmps es:[di],ds:[si]
    • 与repz/repnz/repe/repne连用(repnz表示当cx!=0或者不相等时继续)
      • 如果相同,则改变zf标志位为1,对应的是e/z
      • 如果不同,则改变zf标志位为0,对于的是ne/nz
  • 串扫描

    • scas es:[di]

    • 查找ax或者al的值

    • 找到之后,地址di要-2才是真实的地址

    • 注意匹配最后一个t,判断条件可以用zf当前的值

      • ;lt301a.asm(文件名)
        	.model small	;定义程序的存储模式
        	.stack	;定义堆栈段
        	.data	;定义数据段
            str1 db 'hello'
            str2 db 5 dup(00h)
            length equ str2-str1
                  
            s1 db 'stuDent'
            s2 db 'scudent'
            num equ s2-s1
                  
        	;在数据段定义要显示的字符串
        	.code	;定义代码段
        	.startup	;程序起始点,建立DS、SS
              	
        	push ds
        	pop es
              	
              	
              	
        	mov di,offset s2
        	cld
        	mov cx,num
        	mov al,'t'
        	repnz scasb
        	jz exit
        	nop
        	nop
        	nop
        	exit:
        	nop
              	
        	.exit 0	;程序结束点,返回DOS
        	end	;汇编结束
        
  • 串获取

    • lods ds:[si]
    • 放入ax或者al中
  • 串存入

    • stos es:[di]
    • 将ax或者al内的值存入

BCD码调整

  • DAA(Decimal Adjust Addition)
    • 调整最后的结果
    • 针对8位寄存器(AL、AH等)
  • DAS(Decimal Adjust Subtraction)
    • 调整最后的结果
    • 针对8位寄存器
  • AAA(ASCII Adjust Addition)
    • 调整最后的结果
    • 针对16位寄存器
  • AAS(ASCII Adjust Subtraction)
    • 调整最后的结果
      • 加上ADC AH,0
    • 针对16位寄存器
  • AAM(ASCII Adjust Multiply)
    • 调整最后的结果
    • 针对16位寄存器
  • AAD(ASCII Adjust Division)
    • 做除法前,将被除数从非压缩BCD码转换为二进制数