汇编语言--如何调用子程序

来源:互联网 发布:nginx springmvc 整合 编辑:程序博客网 时间:2024/05/22 07:53

  汇编语言的程序调用:

1:程序内部标号调用

我们来看一个例子:编制一个子程序,求y=x^4,x为字节,y为字,且不会溢出。

1.1:子程序的参数由寄存器bl提供,返回结果在ax中。
  实现如下:
  
assume cs:codesg, ss:stackstack segment    db  32 dup (0)stack endscodesg segmentmain procstart: mov ax,stack       mov ss,ax       mov sp,16       mov bl,08  ;为调用子程序准备参数       call subp       ;子程序调用返回后要做的处理       mov ax,4c00h       int 21hmain endp;强调:从现在始,定义子程序必须要有这样的文档;子程序功能:求y=x^4;入口参数:x的值由bl提供;返回值:y值由ax返回,且y值不会超过1个字的范围subp proc    push cx;子程序中使用的寄存器入栈    mov bh,0;子程序内容    mov dx,0    mov ax,0    mov al,bl    mov cx,3 s: mul bx    loop s    pop cx;子程序使用的寄存器出栈    retsubp endpcodesg endsend start
解析:这个比较简单就不多讲了,看下面的。
1.2:程序不变,主程序中提供如下数据区
data segment x db 1,2,3,4,5,6,7,8 y dw 0,0,0,0,0,0,0,0data ends
子程序完成全部8个数据的求解任务,主程序只调用一次子程序即可。
这个怎么实现?
assume cs:codesg,ss:stack,ds:datadata segment      x db 1,2,3,4,5,6,7,8     y dw 0,0,0,0,0,0,0,0data endsstack segment    db  32 dup (0)stack endscodesg segmentmain procstart: mov ax,stack       mov ss,ax       mov ax,data       mov ds,ax       mov sp,16       mov si,0;       mov di,8 ;为调用子程序准备参数       call subp       mov ax,4c00h  ;子程序调用返回后要做的处理       int 21hmain endp;子程序功能:求y=x^4;入口参数:x的值由bl提供;返回值:y值由ax返回,且y值不会超过1个字的范围subp proc    push cx;子程序中使用的寄存器入栈    push bx    mov bx,0;子程序内容    mov cx,8s1: push cx    mov dx,0    mov ax,0    mov bl,byte ptr [si]    mov al,bl    mov cx,3 s: mul bx    loop s    pop cx;子程序使用的寄存器出栈    mov word ptr [di],ax    add di,2    inc si    loop s1   pop cx   pop bx   retsubp endpcodesg endsend start
解析:主程序只是给出了地址的偏移量。我们要在子程序中实现。首先将要用到的寄存器的值保护起来,入栈,然后使用寄存器
、干我们想干的事(毕竟寄存器在还是稀缺资源)。构建双重循环,一层实现数的遍历,一层要来求数的四次方,每次求完一个数,根据di将其写回内存中去。大体思路就是这样。

2:程序外部如何调用?

要求:将上面的程序2按多文件的方式存放。
代码实现:
子程序:


;子程序功能:求内存中偏移量为si的连续八个数的4次方
;然后将结果放在后面,每个结果数占用一个字
;入口参数:si di,si数的来源偏移量,di结果放置的偏移量
;返回值:返回 8个数的4次方,放在di指定的内存中masm
public subp
assume cs:code
code segment
start:
subp proc
    push cx;子程序中使用的寄存器入栈
    mov bx,0;子程序内容
    mov cx,8;外层循环八次
s1: push cx;外层循环量入栈
    mov dx,0
    mov ax,0;初始化将要用的寄存器
    mov bl,byte ptr [si];从内存取出数
    mov al,bl;放入ax,再连乘3次就是bl的4次方
    mov cx,3
 s: mul bx
    loop s
    pop cx;子程序使用的寄存器出栈
    mov word ptr [di],ax
    add di,2
    inc si
    loop s1
   pop cx;恢复,原来cx的值
   ret
subp endp
code ends
end start


主程序:

extrn subp :farassume cs:codesg,ss:stack,ds:datadata segment      x db 1,2,3,4,5,6,7,8     y dw 0,0,0,0,0,0,0,0data endsstack segment    db  32 dup (0)stack endscodesg segmentmain procstart: mov ax,stack       mov ss,ax       mov ax,data       mov ds,ax       mov sp,16       mov si,0;       mov di,8 ;为调用子程序准备参数       call far ptr subp       mov ax,4c00h  ;子程序调用返回后要做的处理       int 21hmain endpcodesg endsend start


解释:首先在子程序中有 public subp,表示程序中标号为subp的地方为公有的,类似于c++和java,其他程序可以调用。
在主程序中有个 extrn subp:far,表示本程序要用到一个外部程序,入口地址在标号为subp处,经远转移可到达。
编译的时候两个文件单独编译,link的时候 要 link 1.obj+2.obj 将两个文件link在一起,执行的时候只需执行1.exe。

                                             
0 0
原创粉丝点击