zoukankan      html  css  js  c++  java
  • 汇编入门学习笔记 (九)—— call和ret

    疯狂的暑假学习之  汇编入门学习笔记 (九)——  call和ret


    參考: 《汇编语言》 王爽 第10章


    call和ret都是转移指令。


    1. ret和retf


    ret指令:用栈中的数据,改动IP内容,从而实现近转移

    相当于:

    pop ip

    retf指令:用栈中的数据。改动CS和IP,从而实现远转移

    相当于:

    pop ip

    pop cs


    样例:ret

    assume cs:code,ss:stack
    
    stack segment
    	db 16 dup(1)
    stack ends
    
    code segment
    	mov ax,4c00H
    	int 21H
    
    start:	mov ax,stack
    	mov ss,ax
    	mov sp,16
    	
    	mov ax,0
    	push ax
    	ret
    	
    code ends
    
    end start

    retf

    assume cs:code,ss:stack
    
    stack segment
    	db 16 dup(1)
    stack ends
    
    code segment
    	mov ax,4c00H
    	int 21H
    
    start:	mov ax,stack
    	mov ss,ax
    	mov sp,16
    	
    	mov ax,0
    	push cs
    	push ax
    		
    	retf
    	
    code ends
    
    end start


    2. call指令


    call指令,运行操作:

        1.将当前IP或CS和IP压入栈中

        2.跳转


    (1)根据位移进行转移的call指令


    格式: call 标号


    将下一条的指令的ip压入栈中。在转到标号处


    相当于:


    push ip

    jmp near ptr 标号



    (2)转移的目的地址在指令中的call指令


    格式:

    call far ptr 标号


    将下一条的指令的CS和IP压入栈中。在转到标号处


    相当于:

    push cs

    push ip

    jmp far ptr


    (3)转移地址地址在寄存器中的call指令


    格式:call 16位reg


    相当于:

    push ip

    jmp 16位reg


    (4)转移地址在内存中的call指令

       1. call word ptr 内存单元

            相当于:

                 push ip

                 jmp word ptr 内存单元

       2. call dword ptr 内存单元

            相当于:

                  push cs

                  push ip

                  jmp dword ptr 内存单元


    3. mul 指令


    mul 是乘法指令


    表示两个数相乘,它必须是都是8位或者都是16位


    8位相乘 结果默认存放在ax中

    16位相乘 结果高位存放在dx中。低位存放在ax中

    样例见以下。



    3. call和ret配合使用


    call于ret结合使用。就相当于函数。 


    样例:求dw中数值的3次方。把bx当做“函数”參数,ax当做“函数”的返回值。

    assume cs:code,ds:data
    
    data segment
    	dw 1,2,3,4,5,6,7,8
    	dd 0,0,0,0,0,0,0,0
    data ends
    
    code segment
    	start:	mov ax,data
    		mov ds,ax
    		
    		mov si,0
    		mov di,16
    		mov cx,8
    	s:	mov bx,ds:[si]
    		call cube
    		mov ds:[di],ax
    		mov ds:[di+2],dx
    		
    		add si,2
    		add di,4
    		loop s
    			
    		mov ax,4c00H
    		int 21H
    			
    			
    	cube:	mov ax,bx
    		mul bx
    		mul bx
    		ret
    			
    				
    code ends
    
    end start


    寄存器数量有限,假设要传的參数。或者返回的參数过多。

    能够使用内存,或者栈。


    样例:小写转大写。(用内存存放參数)


    assume cs:code,ds:data
    
    data segment
    	db 'conversation'
    data ends
    
    code segment
    	start:	mov ax,data
    		mov ds,ax
    		
    		mov si,0
    		mov cx,12
    		call captial
    		
    		mov ax,4c00H
    		int 21H
    			
    captial:and byte ptr ds:[si],11011111b
    		inc si
    		loop captial
    			
    code ends
    
    end start


    样例:计算 (a - b) ^3  如果a=3,b=1 (用栈来存放參数)

    assume cs:code
    
    code segment
    	start:	mov ax,1
    		push ax
    		mov ax,3
    		push ax
    		call difcube
    		
    		mov ax,4c00H
    		int 21H
    		
    difcube:push bp
    		mov bp,sp
    		mov ax,[bp+4]
    		sub ax,[bp+6]
    		mov bp,ax
    		mul bp
    		mul bp
    		pop bp
    		
    		ret 4
    code ends
    
    end start


    上面代码中的 ret 4 表示:

    pop ip

    add sp,n


    样例:小写转大写,用0结尾来推断。(用栈来处理寄存器冲突)

    assume cs:code,ds:data
    
    data segment
    	db 'word',0
    	db 'city',0
    	db 'good',0
    data ends
    
    code segment
    	start:	mov ax,data
    		mov ds,ax
    		mov cx,3
    		
    		mov bx,0
    	s:	push cx
    		mov si,bx
    		call capital
    		add bx,5
    		pop cx
    		loop s
    			
    		mov ax,4c00H
    		int 21H
    			
    capital:mov cl,[si]
    		mov ch,0
    		jcxz ok
    		and byte ptr [si],11011111b
    		inc si
    		jmp short capital
    		ok:	ret		
    code ends
    
    end start

    注意:要用栈保存cx



    样例:实现show_str “函数”  在屏幕显示字符串。

    用dh指定函数 。dl指定列号,cl指定颜色

    assume cs:code,ds:data,ss:stack
    
    data segment
    	db 'Welcome to masm!',0
    data ends
    
    stack segment
    	dw 8 dup(0)
    stack ends
    
    code segment
    	start:	mov ax,data
    		mov ds,ax
    		mov ax,stack
    		mov ss,ax
    		mov sp,16
    		
    		mov dh,10  ;行
    		mov dl,17  ;列
    		mov cl,2   ;颜色
    		mov si,0
    		call show_str
    			
    		mov ax,4c00h
    		int 21h
    		
    show_str:	push ax
    		push di
    		push dx
    			
    		mov ax,10   ;确定行段 es
    		mul dh
    		add ax,0b800h
    		mov es,ax
    		
    		mov dh,0    ;确定列偏移 di,注意。一个字符两个字节
    		add dx,dx
    		mov di,dx
    			
    			
    	s: 	push cx    ;保存cx
    			
    		mov ch,0
    		mov cl,ds:[si]
    		jcxz ok      ;假设为0 跳转
    		
    		mov es:[di],cl
    		pop cx
    		mov es:[di+1],cl
    		
    		inc si
    		add di,2
    		jmp short s
    			
    			
    			
    	ok:	pop cx    ;不要忘记pop,眼不让rec还原的ip就不正确了
    		pop dx
    		pop di
    		pop ax
    		ret
    			
    
    code ends
    
    end start





  • 相关阅读:
    【算法学习笔记】树状数组
    【算法学习笔记】前缀和与差分
    【算法学习笔记】RMQ问题与ST表
    【算法学习笔记】倍增求最近公共祖先(LCA,非战斗机)
    使用Ajax Web.config配置
    GridView导出Excel
    [OFBiz]简介 二
    [OFBiz]开发 一
    JAVACC详解
    Ofbiz 10.04 + eclipse 安装与配置
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6713947.html
Copyright © 2011-2022 走看看