• 汇编笔记_第十章



    title: 汇编笔记_第十章
    date: 2018-12-28 18:18:50

    • 笔记
      categories:
    • 汇编语言

    call和ret指令

    ret和retf

    • 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;
    • 前者相当于:
      pop IP
      后者相当于
      pop IP
      pop CS

    call指令

    CPU执行call指令,进行两步操作:

    • 将当前的IP或CS和IP压入栈中;
    • 转移

    call指令 不能实现短转移,除此之外与jmp的原理相同;

    依据位移进行转移

    指令格式:
    call 标号
    将当前的IP压栈后,转到标号处执行;(入栈的是call指令后的第一个字节偏移地址入栈),段内转移;

    • (sp)=(sp)-2;((ss)*16+(sp))(ip)
    • (ip)=(ip)+16位位移

    相当于:

    push IP

    jmp near ptr 标号

    eg:

    内存地址    机器码    汇编指令
    1000:0     b8 00 00  mov ax,0
    1000:3     e8 01 00  call s
    1000:6     40        inc ax
    1000:7     58        s:pop ax
    
    最后ax的值为:6h,因为执行call s时,push ip (ip)=6h,之后pop ax,(ax)=6h
    

    转移的目的地址在指令中

    • call far ptr 标号实现的是段间转移;

    • (sp)=(sp)-2

    • ((ss)*16+(sp))=(cs)

    • (sp)=(sp)-2

    • ((ss)*16+(sp))=(ip)

    • (cs)=标号所在的段地址;

    • (ip)=标号所在的偏移地址;

    eg:

    内存地址    机器码          汇编指令
    1000:0     b8 00 00        mov ax,0
    1000:3     9A 09 00 00 10  call far ptr s
    1000:8     40              inc ax
    1000:9     58              s:pop ax
                               add ax,ax
                               pop bx
                               add ax,bx
    

    指令执行后,(ax)=1010h

    执行call时,push cs , push ip,(cs)=1000h,(ip)=8h;

    pop ax后,(ax)=8h,add ax,ax后(ax)=10h,pop bx后(bx)=1000h,最后add ax,bx,(ax)=1010h;

    转移地址在寄存器中

    格式:
    call 16位寄存器

    功能:

    • (sp)=(sp)-2
    • ((ss)*16+(sp))=(ip)
    • (ip)=(16位寄存器)

    相当于进行:

    push ip

    jmp 16位reg

    eg:

    内存地址    机器码    汇编指令
    1000:0     b8 06 00  mov ax,6
    1000:3     ff d0     call ax
    1000:5     40        inc ax
    1000:6               mov bp,sp
                         add ax,[bp]
    

    程序执行完后,(ax)=0bh;

    转移地址在内存中

    两种格式:

    • call word ptr 内存单元地址

    相当于:

    push ip
    jmp word ptr 内存单元地址

    • call dword ptr 内存单元地址

    相当于:


    push cs

    push ip

    jmp dword ptr 内存单元地址

    eg:

    assume cs:code
    stack segment
    dw 8 dup (0)
    stack ends
    code segment
    start:
    mov ax,atack
    mov ss,ax
    mov sp,16
    mov ds,ax
    mov ax,0
    call word ptr ds:[0EH]
    inc cx      ;设这个地方的地址为0000:xx
    inc cx
    inc cx
    
    mov ax,4c00h
    int 21h
    
    code ends
    end start
    

    程序执行到call前,堆栈段和数据段合并,执行call时(ip)=x,入栈,也是数据段ds:[0EH]处的数据为x,这是跳到x处的指令也就是inc ax,,三次inc后(ax)=3h;

    call和ret的配合使用

    assume cs:code
    code segment
    start:
    mov ax,1
    mov cx,3
    
    call s
    mov bx,ax
    mov ax,4c00h
    int 21h
    
    s:
    add ax,ax
    loop s
    ret
    
    code ends
    end start
    

    cpu执行的主要过程:

    • CPU执行到call s指令时,ip指向后一句mov bx,ax处,并将其压栈,之后修改ip到s处,实现程序的跳转;
    • 在s中,s实现的时求 (2^{cx}),cx的值由最开始的指令给出;
    • 执行完后,ret指令将栈中的值弹出赋给ip,程序跳转到call后的mov bx,ax处,最后结束;

    子程序的框架

    标号:
        指令
        ret
    

    模块化程序的设计

    伪指令proc

    格式:

    子程序名 PROC 属性
    ......
    子程序名 ENDP
    

    过程属性

    • 属性分为NEAR属性和FAR属性,默认为NEAR,主程序和子程序在 同一个代码短 使用 NEAR 属性,否则使用 FAR 属性;
    • call执行时,系统根据子程序名的属性决定保存断点的段地址和偏移地址;

    近程调用NEAR

    code segment
        main proc far
            ...
            call subr1
            ...
    
    
        subr1 proc near
            ...
            ret
        subr1 endp
    
    
        main endp
    
    code ends
    

    code segment
        main prco far
            ...
            call sunr1
            ...
        main endp
    
        subr1 proc near
            ...
            ret
        subr1 endr
    
    code ends
    

    远程调用NEAR

    code1 segment
        main proc far
            ...
            call subrx
            ...
            mov ah,4ch
            int 21h
        main endp
    code1 ends
    
    code2 segment
        ...
        call subrx
        ...
    
        subrx proc far
            ...
            ret
        subrx endp
    
    code2 ends
    

    现场保护

    主程序调用子程序时可能寄存器的值会被改变,需要保存此时的值后再进入子程序,一般的实现是利用栈来保存可能改变的寄存器的值,退出子程序时pop恢复现场;

    mul指令

    • mul是无符号数乘法指令;
    • 格式:
      mul reg
      mul 内存单元

    不同位的相乘:

    • 8位:al和9位寄存器或内存单元相乘,结果在al中;
    • 16位:ax和16位寄存器或内存单元相乘,结果高位在dx中,低位在ax中;


    • 相乘的两个数要么是8位要么是16位;

    内存单元可用不同的寻址方式给出:

    • mul byte ptr ds:[0]
      含义:(ax)=(al)*((ds)*16+0)

    • mul word ptr [bx+si+8]
      含义:
      (ax)=(al)*((ds)*16+(bx)+(si)+8)
      (dx)=(al)*((ds)*16+(bx)+(si)+8)

    • 结果大于255就用16位的

    xchg指令

    • 指令格式:xchg oprd1,oprd2
    • 功能:将一个字节或一个字的源操纵数和目的操作数相交换;
    • 交换的指令可以在寄存器之间,寄存器与储存器之间:
    xchg reg,reg
    xchg reg,mem
    xchg mem,reg
    

    xchg 指令不允许的情况:

    • 不能同时都为内存操作数
    • 任何一个操作数都不能为段寄存器
    • 任何一个操作数不能为立即数
    • 两个操作数的长度必须相等

    https://www.cnblogs.com/31415926535x/p/10197667.html

    (end)

  • 相关阅读:
    操作系统学习笔记:银行家算法的回顾和训练
    操作系统学习笔记:内存学习随笔
    操作系统笔记:内存的连续管理
    操作系统笔记:内存的离散管理
    操作系统:内存管理复习ing之页面置换算法
    马原学习日记1:实践
    bootstrap简单教程
    css-6(媒体识别)
    css-5(弹性盒子)
    css-3(旋转+过渡)
  • 原文地址:https://www.cnblogs.com/31415926535x/p/10197667.html
Copyright © 2020-2023  润新知