• 汇编学习笔记(7)call和ret指令


    ret和retf

    CPU执行ret指令时进行以下两步操作:

    (IP)=((ss)*16+(sp))
      (sp)=(sp)+2

    这相当于pop IP

    CPU执行retf指令时进行以下四步操作:

    (IP)=((ss)*16+(sp))
      (sp)=(sp)+2
      (cs)=((ss)*16+(sp))
      (sp)=(sp)+2

    这相当于pop IP,pop CS,下面这段代码会造成死循环。

     1 ;一个死循环的例子
     2 assume cs:codesg,ss:stack
     3 
     4 stack segment
     5 db 16 dup(0)
     6 stack ends
     7 
     8 codesg segment
     9 
    10         mov bx,0
    11         push bx
    12         ;执行ret指令程序转到第一行开始执行
    13         ret
    14         mov ax,4c00h
    15         int 21h
    16 
    17 start:  mov ax,stack
    18         mov ss,ax
    19         mov sp,16
    20         mov ax,0
    21         push cs
    22         push ax
    23         ;执行retf指令程序转到第一行开始执行
    24         retf
    25 
    26 codesg ends
    27 end start
    28 end

    call

    call指令有多形式:call 标号;call far ptr 标号;call reg;call word tr 内存单元;call dword tr 内存单元.

    1.call 标号

    CPU执行call 标号相当于执行:

    push IP
      jmp near ptr 标号

    ps:这里push IP是加上call 标号这条指令长度后的(IP)

    2.call far ptr 标号

    CPU执行call far ptr 标号相当于执行:

    push CS
      push IP   jmp far ptr 标号

    ps:先进行push CS操作我觉得是因为retf指令先进行pop IP操作,以完成子程序的功能

    3.call reg

    CPU执行call reg相当于执行:

    push IP
      jmp reg

    ps:reg特指16位寄存器

    4.call word ptr 内存单元

    CPU执行call word ptr 内存单元相当于执行:

    push IP
      jmp word ptr 内存单元

    5.call dword ptr 内存单元

    CPU执行call dword ptr 内存单元相当于执行:

    push CS
      push IP
      jmp dword ptr 内存单元

    子程序

    从ret和call的功能不难看出这两个指令是设计用来配合使用的,可以达到子程序的效果,和高级语言的函数很像,下面这段代码依然是死循环。

     1 ;一个死循环的例子
     2 assume cs:codesg,ss:stack
     3 
     4 stack segment
     5 db 16 dup(0)
     6 stack ends
     7 
     8 codesg segment
     9 
    10 start:  mov ax,stack
    11         mov ss,ax
    12         mov sp,16
    13         call s
    14 s:      mov ax,offset s
    15         push ax
    16         ret
    17         mov ax,4c00h
    18         int 21h
    19 codesg ends
    20 end start
    21 end

    mul

    mul是乘法指令,有两种情况:

    1.8位乘法,两个相乘的数都是8位则一个数放在al中,另一个放在8位reg或内存单元中,结果存储在ax中

    2.16位乘法,两个相乘的数都是16位则一个数放在ax中,另一个放在16位reg或内存字节单元中,结果高位存储在dx中,地位存储在ax中

    到目前为止,加减乘除四种基本运算指令都已经学过了,下面写个小程序做次总结。

     1 ;基本的算数运算指令
     2 assume cs:codesg
     3 
     4 codesg segment
     5 
     6     mov al,0
     7     add al,2
     8     mov cx,6
     9 s:  add al,al
    10     loop s
    11     ;al累加6次得结果128
    12 
    13     mov bl,2
    14     mul bl
    15     ;8位数乘法,ax=0100h
    16 
    17     mov bx,1000d
    18     mul bx
    19     ;16位乘法dx=0003h,ax=e800h
    20 
    21     div bx
    22     ;32除法,ax=0100h
    23 
    24     mov bl,2
    25     div bl
    26     ;16除法,al=128
    27 
    28     sub al,al
    29     ;减法操作ax=0
    30     
    31 codesg ends
    32 
    33 end
  • 相关阅读:
    Ckeditor(4.5.5) language 语言切换
    利用array_slice进行手动分页
    PHP API 接口访问之签名验证
    mysql外键的一些总结
    缺货置顶功能(类似功能可参考)
    [Exchange2013] 无法正常发送存入草稿箱 或者 只能发不能收
    [Exchange]2个不同域之间互发邮件
    [Citrix NetScaler] 简述
    [转载] cookie、JS记录及跳转到页面原来的位置
    [XenServer] XenServer修改IP 以及 root密码
  • 原文地址:https://www.cnblogs.com/michaelle/p/4023321.html
Copyright © 2020-2023  润新知