• 汇编语言复习提纲


    汇编语言复习提纲

    考试时间:十六周周一
    考试形式:笔试
    考试范围:第一章-第九章
    题型:填空、简答、程序设计
    教材:IBM-PC汇编语言程序设计(第二版)
    作者:@TheSilverMoon
    博客:https://www.cnblogs.com/TheSilverMoon/

    第一章

    1. 进制转换
    2. 补码加法、减法
    3. 与或非、异或运算



    第二章

    80x86寄存器组

    • ax(accumulator),做为累加器用,在乘除等指令中指定用来存放操作数
    • bx(base),可以做为通用寄存器,经常用做基址寄存器
    • cx(count),可以做为通用寄存器,常用来保存计数值(比如在loop中)
    • dx(data),可以做为通用寄存器,一般在双字长运算时把dx和ax组合在一起存放一个双字长数,dx存高位。
    • sp(stack pointer)堆栈指针寄存器(指示段顶偏移地址)
    • bp(base pointer)基址指针寄存器(堆栈区中的一个基地址)
    • si(source index)源变址寄存器和di(destination index)目的变址寄存器一般与ds联用,用来确定数据段中某一存储单元的地址。串处理指令中,si和di做为隐含的源变址和目的变址寄存器。
    • ip(instruction pointer)指令指针寄存器,用来存放代码段中的偏移地址
    • flags 标志寄存器


    条件码

    • of(overflow)操作数超出了机器能表示的范围时为1
    • sf(sign flag)记录运算结果的符号,负置1
    • zf(zero flag)运算结果为0时,置1
    • cf(carry flag)进位标志,进位置1
    • af(auxiliary carry flag)记录第三位(半个字节)产生的进位值
    • if(interrrupt flag)if为1时,CPU正常响应可屏蔽中断请求

    80x86地址总线为20位 1m=2^20,当机器字长为16位时,大部分数据是以字为单位,存放时,低位字节放入低地址,高位字节放入高地址,如存放5678h,低位78h存放在0004h单元中,高位56h存放在0005h单元中


    20位物理地址由16位段地址和16位偏移地址组成,段地址左移4位(16进制左移1位)再加上偏移地址即为物理地址。




    第三章

    80x86寻址方式

    • 立即寻址方式
      例:mov al(八位寄存器),5(源操作数)
    • 寄存器寻址方式 例:mov ax,bx 16位寄存器:ax,bx,cx,dx,si,di,sp,bp 8位寄存器:al,ah,bl,bh,cl,ch,dl,dh
    • 直接寻址方式
      例:mov ax(16位寄存器),[2000h](EA)
      EA(Effective Address)=基址+(变址X比例因子)+位移量
      加中括号表示偏移地址,默认在DS
      可以使用段跨越前缀,如mov ax,ES:[2000h],但在某些情况下不可以使用段跨越前缀(书P39)
    • 寄存器间接寻址方式 例:mov ax,[bx] 若ds=2000h,bx=1000h 物理地址=20000+1000=21000h
    • 寄存器相对寻址方式
      move ax,count[si] count为16位位移量的符号地址 类似的,可以有mov eax,table[ESI]esi内容指向此表格中的一项
      适用于字符串、数组、表格的处理
    • 基址变址寻址方式 例:mov ax,[bx][di]或mov ax,[bx+di]

    段内直接寻址:
    指令格式为:

    jmp near ptr progia
    jmp short quest
    

    如果位移量为16位,在符号地址前加near ptr操作符;如果为8位,在其之前加short

    段内直接寻址:

    jmp bx
    

    80x86指令系统

    数据传送指令:

    mov 传送
    movsx 带符号扩展传送
    push 进栈
    pop 出栈
    xhcg 交换
    lea 有效地址送寄存器

    lea reg,src ;把源操作数的有效地址送到指定寄存器当中
    

    类型转换指令:

    cbw 字节转换成字
    cwd 字转换为双字

    1. 执行的操作:al的内容符号扩展到ah,形成ax中的字。即如果al的最高有效位为0,则ah为0;如al的最高有效位为1,则ah=0ffffh
    2. 执行的操作:ax的内容符号扩展到dx,形成dx:ax中的双字

    算数指令:

    add 加法
    adc 带进位加法
    inc 加一
    xadd 交换并相加
    sub 减法
    sbb 带借位减法
    dec 减一
    cmp 比较
    mul 无符号乘法
    imul 带符号乘法
    div 除法
    idiv 带符号除法

    add dst,src  
    adc dst,src
    adc dst.src
    inc opr ;opr是操作数的意思
    ;除inc指令不影响cf外,其他都影响条件标志位 
    ;of 可以用来表示带符号数的溢出,cf可以表示无符号数的溢出  
    
    sub dst,src
    sbb dst,src
    dec opr ;
    cmp opr1,opr2;执行减法操作,但是不保存结果,只是根据结果设置条件标志位,后面往往跟着一条条件转移指令,根据结果产生不同的程序分支
    
    mul src
    ;字节操组数: ax <- al * src  两个八位数相乘得到的十六位数,存在ax;字操作数: (dx.ax) <- ax * src  两个八位数相乘得到的十六位数,存在dx,ax中;dx存高位,ax存低位
    
    div src  ;16位被除数在ax中,8位除数为源操作数,结果的8位商在al中,8位余数在ah中  
    idiv src  ;32位的被除数在dx,ax中,16位除数为源操作数,结果的16位在ax中,16位的余数在dx

    逻辑指令:

    and 逻辑与
    or 逻辑或
    not 逻辑非
    xor 异或
    test 测试

    and  dst,src
    or des,src
    not opr
    xor dst,src
    test opr1,opr2 ;两个操作数想与,结果不保存,只根据其特征置条件码
    ;not 不允许使用立即数,其他的至少有个一个操作数必须存放在寄存器中
    
    

    位移指令:

    shl 逻辑左移
    sal 算术左移
    shr 逻辑右移 sar 算术右移
    rol 循环左移
    ror 循环右移
    rcl 带进位左移
    rcr 带进位右移

    shl opr,cnt
    sal opr,cnt
    sar opr,cnt
    rol opr,cnt
    ror opr,cnt
    rcl opr,cnt
    rcr opr,cnt
    

    如果大于cnt大于1,则需要存在cl中,cf保存移出的最后一位


    串处理指令:

    movs 串传送
    cmps 串比较
    ins 串输入
    outs 串输出
    rep 重复
    repe 相等则重复
    repne 不相等则重复

    rep string primitive ;string primitive可为各种指令
    movs dst,src
    

    条件转移指令:

    jz(jump if zero) 结果为0则转移
    jnz(jump if not zero) 结果不为0则转移
    js(jump if sign) 结果为负则转移 jns(jump if not sign) 结果为正则转移
    jbe(jump if below or equal)低于或等于,或不高于则转移
    jnbe(jump if not below or equal,or not above) 不低于或等于,或高于则转移
    jge 不小于则转移 jng 不大于则转移


    循环指令:

    loop 循环
    loopz 相等或为0时循环
    loopnz 不相等或不为0时循环


    子程序:

    call 调用
    ret 返回

    call dst  
    ret 
    

    中断:

    int中断指令

    int type  
    



    第四章

    伪操作

    assume 伪操作

    明确段和段寄存器的关系
    例:

    assume cs:code,ds:data,ss:stack
    

    数据定义及存储器分配伪操作

    • DB 定义字节,其后的每个操作数都占有一个字节(8位)
    • DW 定义字,其后的每个操作数占有一个字(16位,低位字节在第一个字节地址中,高位字节在第二个字节地址中)
    • DD 定义双字,其后的每个操作数占有两个字(32位)
    data_byte db 10,4,10h
    data_word dw 100,100h,-5
    data_dw dd 3*20,0fffdh
    

    image

    • 操作数'?'可以保留存储空间,但不存入数据
    abc db 0,?,?,0
    
    • dup 复制操作符
    array1 db 2 dup(0,1,2,?)
    array2 db 100 dup(?)
    

    image

    • EQU 表达式赋值伪操作
    constant equ 256
    data equ height+12
    alpha equ 7
    beta equ alpha-2
    addr equ var+beta
    b equ [bp+8]
    p8 equ ds:[bp+8]
    

    地址计数器与对准伪操作

    • '$'地址计数器
      汇编程序使用地址计数器来保存当前正在汇编的指令的偏移地址。开始汇编或在每一段开始时,地址计数器初始化为0,之后每处理一条指令,地址计数器就增加一个值,此值为该指令所需要的字节数
      例:
    array dw 1,2,$+4,3,4,$+4
    

    若汇编时array分配的偏移地址为0074,则存储区如下:
    iamgeTIPS:$只代表该指令的首地址


    数值回送操作符

    • type
    type expression
    

    例:

    array dw 123
    add si,type array
    

    该语句形成为:add si,2
    **如果该表达式是变量,db回送1,dw回送2,dd回送4,如果该表达式为常量,回送0 **

    • length
    length variable
    

    对于变量中使用dup的情况,回送分配给该变量的单元数,其他情况送1

    • size
    size variable
    

    回送分配给该变量的字节数,此值是length和type的乘积

    • offset
    offset variable/label

    回送变量或标号的偏移地址值

    • seg
    seg variable/label

    回送变量或标号的段地址值

    • high&low
    const equ 0abcdh
    mov ah,high const
    

    将汇编成mov ah,0abh



    上机过程(★)

    mount d d:masm
    d:
    masm filename
    link filename
    debug filename.exe / filename.exe
    

    1. 建立asm文件
    2. 用masm程序产生obj文件
    3. 用link程序产生exe文件
    4. 执行程序

    常用命令:

    1. G命令:运行当前在内存中的程序
    2. D命令:显示一定范围内存地址的内容
      格式:d [range]
      如果键入以下命令,Debug 将从 CS:100 开始显示 20h 个字节的内容:
      dcs:100 l 20
      如果键入以下命令,Debug 将显示范围从CS 段的100h 到115h 中所有字节的内容:
      dcs:100 115
    3. R命令:显示或改变一个或多个 CPU 寄存器的内容
      r [register-name]
    4. U命令:反汇编字节并显示相应的原语句,其中包括地址和字节值。反汇编代码看起来象已汇编文件的列表
      u [range]
      参数
      如果在没有参数的情况下使用,则 u 命令分解 20h 字节(默认值),从前面 u 命令所显示地址后的第一个地址开始。
      range
      指定要反汇编代码的起始地址和结束地址,或起始地址和长度。



    第五章

    本章内容老师上课说以作业为主,下面放一下作业的代码

    5.6 编写程序,将一个包含有20个数据的数组m分成两个数组:正数数组p和负数数组n,并分别把这两个数组中数据的个数求出来

    data segment
    	count equ 20
    	array dw 20 dup(?);存放数组
    	count1 equ 0;正数个数
    	array1 dw 20 dup(?)
    	count2 equ 0;负数个数
    	array2 dw 20 dup(?)
    data ends
    
    code segment
    main proc far
    	assume cs:code,ds:data
    start:
    	push ds;设置返回dos
    	xor ax,ax
    	mov ax,data
    	mov ds,ax;给ds赋值
    
    begin:
    	mov cx,count
    	lea bx,array
    	lea si,array1
    	lea di,array2
    
    begin1:
    	mov ax,[bx]
    	cmp ax,0
    	js negative
    	mov [si],ax;是正数,存入数组
    	inc count1
    	add si,2
    	jmp next
    
    negative:
    	mov [di],ax
    	inc count2
    	add di,2
    
    next:
    	add bx,2
    	loop begin1
    	mov al,count1
    	call print
    	mov al,count2
    	call print
    	mov ah,4ch
    	int 21h
    	ret
    main endp
    print proc near
    	aam ;将(AL)中的二进制数转换为二个非压缩 BCD 码,AH←AL/10(商),AL←AL%10(余数)
    	add ah, 0;变为 0~9 的 ASCII mov dl, ah 
    	mov ah, 2   ;显示一个字符的 DOS 调用 
    	int 21H 
    	add al, 0;变为 0~9 的 ASCII mov dl, al 
    	mov ah, 2   ;显示一个字符的 DOS 调用 
    	int 21h 
    	ret 
    code ends
    	end start
    

    5.7 试编制一个汇编语言程序,求出首地址为data的100d字数组中的最小偶数,并将其存在ax中

    dsg segment
    	data dw 100 dup(?)
    dsg ends
    
    code segment
    main proc far
    	assume cs:code,ds:dsg
    
    start:
    
    begin:
    	mov bx,0
    	mov cx,100
    
    comp:
    	mov ax,data[bx]
    	add bx,2
    	test ax,01h ;判断是否是偶数
    	loopnz comp;loop not zero ,继续比较下一个
    	jnz stop
    	jcxz stop;若cx=0,则最后一个是偶数,即为最小偶数
    
    comp1:
    	mov dx,data[bx]
    	add bx,2
    	test dx,01h
    	jnz next;不是,比较下一个数
    	cmp ax,dx ;ax<dxjle next 
    	mov ax,dx
    next:loop comp1
    stop:ret
    
    main endp
    code ends
    	end start
    
    

    5.12 有一个首地址为MEM的100d字数组,试编制程序删除数组中所有为0的项,并将后续项向前压缩,最后将数组的剩余部分补上0

    data segment
    	mem dw 100 dup(?)
    data ends
    
    code segment
    main proc far
    	assume cs:code,ds:data
    start:
    	push ds
    	xor ax,ax
    	push ax
    	mov ax,data
    	mov ds,ax
    
    begin:
    	mov si,(100-1)*2;SI指向mem末元素的首地址
    	mov bx,-2 ;地址指针的初值
    	mov cx,100 ;count
    
    comp:
    	add bx,2
    	cmp mem[bx],0
    	jz cons
    	loop comp
    	jmp finish;比较完了,无0结束
    
    cons:
    	mov di,bx
    cons1:
    	cmp di,si;到最后了吗
    	jae nomov
    	mov ax,mem[di+2];后面元素向前移
    	mov mem[di],ax
    	add di,2
    	jmp cons1
    
    nomov:
    	mov [si],0;最后元素补0 
    	loop comp
    finish: 
    	ret
    
    main endp
    code ends
    	end start
    
    



    第六章

    子程序

    格式:

    procedure_name proc attribute(near/far)
        .
        .
        .
    procedure_name endp
    

    堆栈过程:
    栈是一种先入后出的数据结构
    pushf 的功能是将标志寄存器的值压栈

    十进制转十六进制和十六进制转十进制
    十进制转十六进制:

    ;_______________________________________________________________
    code segment
    	assume cs:code
    main proc far
    	call DecToBinary
    	call BinaryToHex
    main endp
    
    
    ;_______________________________________________________________
    DecToBinary proc near ;十进制转二进制
    	mov bx,0 ;清空bx
    input:
    	mov ah,1
    	int 21h ;调用dos
    	sub al,30h ;转为二进制(通过ASCIIjl exit ;如果小于0,退出
    	cmp al,9d ;如果大于9
    	jg exit ;直接退出
    	cbw ; 把字节转换成字。AL的内容符号扩展到AH,形成AX中的字
    	;当前数字在axxchg ax,bx ;交换ax,bx中的数字,交换之后ax是0,bx是原来ax中的数字
    	mov cx,10d
    	mul cx
    	xchg ax,bx
    	;把ax中的数字加到bxadd bx,ax
    	jmp input
    exit:
    	ret
    DecToBinary endp
    
    ;_______________________________________________________________
    
    BinaryToHex proc near
    	mov ch,4;cx高位设置为4
    rotate:
    	mov cl,4 ;cx低位设置为4
    	rol bx,cl ;bx中的数左移4mov al,bl ;移到al
    	and al,0fh
    	add al,30h ;把十六进制转换成ASCII
    	cmp al,3ah ;判断是否大于9
    	jl print   ;如果小于9直接输出
    	add al,7h  ;A-F
    
    print:
    	mov dl,al ;把要打印的ASCII放到dlmov ah,2
    	int 21h ;调用dos
    	dec ch
    	jnz rotate
    	ret
    BinaryToHex endp
    
    
    code ends
    	end main
    

    十六进制转十进制:

    code segment
    main proc far
    	assume cs:code
    star:
    	push ds
    	sub ax,ax
    	push ax
    
    	call hToB
    	call bTOD
    	jmp main
    	ret
    main endp
    ;____________________________________________
    hToB proc near
    newchar:
    	mov bx,0
    	mov,ah,1
    	int 21h
    	sub al,30h;ascii码转成二进制
    	jl exit
    	cmp al,10d ;是否大于9
    	jl add_to  
    
    	sub al,27h  ;ascii码转成二进制
    	cmp al,0ah
    	jl exit  ;小于a则没有字母,直接跳出
    	cmp al,10h 
    	jge exit
    add_to:
    	mov cl,4
    	shl bx,cl
    	mov ah,0
    	add bx,ax
    	jmp newchar
    exit:
    	ret
    hToB endp
    ;____________________________________________
    bTOD proc near
    	mov cx,10000d
    	call dec_div
    	mov cx,1000d
    	call dec_div
    	mov cx,100d
    	call dec_div
    	mov cx,10d
    	call dec_div
    	mov cx,1d
    	call dec_div
    	ret
    ;____________________________________________
    dec_div proc near
    	mov ax,bx ;低位
    	mov dx,0 ;高位置0
    	div cx 
    	mov bx,dx 	  
    	mov dl,al;要输出的放入dladd dl,30h ;转换成ascii
    	mov ah,2
    	int 21h
    	ret
    dec_div endp
    ;____________________________________________
    bTOD endp
    code ends
    	end start
    
    



    第七章

    宏定义

    宏定义、宏调用、宏展开

    1. 定义:
      macro_name macro [dummy parameter list] 宏定义名 macro 哑元表(形参) · · · endm
    2. 调用
      macro_name [actual parameter list]

    宏定义体=>复制到宏定义位置

    &操作符
    展开时可以把&前后两个符号合并形成一个符号,这个符号可以是操作码、操作数或者一个字符串

    %expresion
    把跟在%之后的表达式的值转换成当前基数下的数,在展开期间用这个数取代哑元

    宏库的调用

    扩展名为.MAC或者.INC 引用格式:

    include c:macro.mac

    子程序与宏定义的区别:
    使用子程序,需要为转子和返回、保存和恢复寄存器以及参数的传递等增加程序的额外开销,子程序是在程序运行期间由主程序调用的,他只占有自身大小的一个空间;而宏调用是在汇编期间展开的,每调用一次都把宏展开一次因而占用空间与调用次数有关,次数越多占用空间越大。




    第八章

    中断

    软件中断:

    1. 由中断指令引起
    2. 由于cpu某些错误引起
    3. 为调试程序debug设置的中断

    硬件中断:

    1. 非屏蔽中断
    2. 来自外部设备的中断(可屏蔽中断)

    FLAGS中:IF=1 允许中断,IF=0 不允许中断

    STI:IF置1
    CLI:IF置0

    中断号*4 -> 偏移地址 -> 下一个字 段地址

    中断过程:

    1. 取中断号N
    2. 标志寄存器flags入栈
    3. 代码段寄存器cs入栈
    4. 指令计数器ip入栈
    5. IF=0,TF=0
    6. 从中断向量表取4 * N的字内容送ip,取4 * N + 2中的字送cs
    7. 转中断处理程序



    第九章

    1号功能
    从键盘输入一个字符并回显在屏幕上 al=字符

    2号功能
    显示器输出,要输出的字符放在dl中

    9号功能
    显示字符串,DS:DX=串地址,必须要$结尾

    A号功能
    键盘输入到缓冲区,DS:DX缓冲区首地址,DS:DX+1=实际输入的字符

  • 相关阅读:
    antd4.x Form组建改变
    react hook 使用注意点
    Dockerfile怎么编写
    在spring boot中3分钟上手阿里巴巴服务熔断系统sentinel
    容器和镜像的导入导出及部署
    设计模式之 ==> 装饰器设计模式
    Jenkins + Gradle + Docker 自动化部署 SpringBoot 项目到远程服务器
    Linux运维常用的40个命令总结
    ceph集群部署
    tcpdump常用命令
  • 原文地址:https://www.cnblogs.com/TheSilverMoon/p/10957476.html
Copyright © 2020-2023  润新知