汇编子程序调用及返回

汇编子程序调用及返回,第1张

程序毫无关系。

主程序结构有毛病,有二:

1、未给数据段、堆栈段寄存器赋值;

2、MOV BX,0B125H

CALL SHOWHEX

之后,未直接结束程序,而是又继续执行子程序

只跟你说一下大体思想吧。其他的还是你自己作比较好。

1用指针SI和DI分别指向数据区和存储区首字节,则A2首地址为[SI+LENG],同样SUB1首地址为[DI+LENG]

然后用MOV AX,[SI];MOV BX,AX;ADD AX,[SI+LENG];MOV [DI],AX;MOV AX,BX;

SUB [SI+LENG];MOV [DI+LENG],AX然后指针后移ADD SI,2(如果是字节变量则为1)

2十进制转二进制就是用除2的办法。用DIV指令,对于字变量,商在AX中,余数在DX中。DX中的值只可能为1或0。再用SHR和ROR指令将DX的值移入寄存器BX中,注意所移动的位数。当AX中的值为1或0时,将其移入BX即结束。

显示的话,需将结果每一位转成ASCII码即可。

转八进制只需将转好的二进制从低到高三位一组转成ASCII码即可。还是使用移位指令,每次移三位即可。

push ax ; ax 的数据压入堆栈

pop ax ; 出栈 恢复 ax 数据

调用子程序前为了 保存 ax 的数据 不 受到影响,返回时 恢复原来的数据。

如果子程序不用到 ax 则可以 省去上述 *** 作。

        CODE  SEGMENT

              ASSUME    CS:CODE

              ORG       100H

      START:  PUSH      CS

              POP       DS

              PUSH      CS

              POP       ES

              MOV       DI,0

              MOV       SI,0

              MOV       BX,10

     @MAIN1:  MOV       CX,BX

              CALL      FACT

              ADD       SI,AX

              ADC       DI,DX

              DEC       BX

              JNZ       @MAIN1

              

              MOV       AX,SI

              MOV       DX,DI

              CALL      DISPDXAX

              MOV       AH,4CH

              INT       21H

; cx中存放要求阶乘的数 

; 阶乘结果在dx、ax中 

        FACT  PROC      NEAR

              PUSH      BX

              PUSH      SI

              PUSH      DI

              PUSHF

              MOV       DX,0

              MOV       AX,1

     @FACT1:  MOV       BX,CX

              CALL      MULT

              LOOP      @FACT1

              POPF

              POP       DI

              POP       SI

              POP       BX

              RET

        FACT  ENDP

; 将要显示的无符号数置于 ax 中 

      DISPAX  PROC      NEAR

              PUSH      BX

              PUSH      CX

              PUSH      DX

              PUSH      SI

              PUSH      DS

              PUSH      CS

              POP       DS

              MOV       BYTE PTR NZ,0

              PUSH      AX

              LEA       SI,DIVARR

              MOV       CX,5

         @1:

              POP       AX

              MOV       DX,0

              MOV       BX,[SI]

              DIV       BX

              PUSH      DX

              CMP       AL,0

              JNE       @2

              CMP       BYTE PTR NZ,1

              JE        @2

              CMP       CX,1

              JE        @2

              MOV       DL,20H

              JMP       @3

         @2:

              ADD       AL,30H

              MOV       DL,AL

              MOV       BYTE PTR NZ,1

         @3:

              MOV       AH,2

              INT       21H

              INC       SI

              INC       SI

              LOOP      @1

              POP       DX

              POP       DS

              POP       SI

              POP       DX

              POP       CX

              POP       BX

              RET

      DIVARR  DW        10000,1000,100,10,1

          NZ  DB        0

      DISPAX  ENDP

; 无符号乘法子程序 (mul指令只能实现16位乘16位,本子程序实现32位乘16位--限定数的大小,结果仍为32位) 

; 被乘数放置于dx,ax 中, 乘数放置于 bx中 

; 结果放置于dx,ax中(dx为高16位,ax为低16位) 

        MULT  PROC      NEAR

              PUSH      CX

              PUSH      SI

              PUSH      DI

              PUSHF

              MOV       SI,0

              MOV       DI,0

              CMP       BX,0

              JE        @MULTEXIT

     @MULT1:  SHR       BX,1

              JNC       @MULT2

              ADD       SI,AX

              ADC       DI,DX

     @MULT2:  SHL       AX,1

              RCL       DX,1

              CMP       BX,0

              JNE       @MULT1

              MOV       DX,DI

              MOV       AX,SI

              POPF

              POP       DI

              POP       SI

              POP       CX

              RET

  @MULTEXIT:

              MOV       AX,0

              MOV       DX,0

              POPF

              POP       DI

              POP       SI

              POP       CX

              RET

        MULT  ENDP

; 将要显示的32位无符号数置于dx、ax中 

    DISPDXAX  PROC      NEAR

              MOV       WORD PTR [Y],AX

              MOV       WORD PTR [Y+2],DX

       ; 以下将 Y (16进制)转为10进制串并输出

              MOV       AX,WORD PTR [Y]         ;=====

              MOV       DX,WORD PTR [Y+2]       ;=====

              MOV       BX,WORD PTR [Z]         ;=====  这一段是关键,加上后不会出现除法溢出

              MOV       CX,WORD PTR [Z+2]       ;=====

              MOV       WORD PTR N,0            ;=====

        MM0:  INC       WORD PTR N  ;=====

              SUB       AX,BX       ; 不停地减 10万 ,得到被10万除的商,放在 n 中

              SBB       DX,CX       ;=====

              JNC       MM0         ;=====

              DEC       WORD PTR N  ;  保存 高5位

              ADD       AX,BX       ;=====

              ADC       DX,CX       ;=====

              MOV       WORD PTR[Y],AX          ;=====

              MOV       WORD PTR[Y+2],DX        ;=====

      ;==============

        MM1:  LEA       DI,CC

              ADD       DI,9

         M2:

              MOV       AX,WORD PTR [Y]

              MOV       DX,WORD PTR [Y+2]

              MOV       BX,10000

              DIV       BX          ; 这里是发生溢出之处

              PUSH      AX

              PUSH      DX

      ; ============

      ; 以下转换10进制的低4位

              POP       DX

              MOV       CX,4

              MOV       AX,DX

         M3:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M3

      ; ===========

      ; 以下转换10进制的高万位

              POP       AX

              MOV       CX,1

         M4:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M4

      ;=============

              MOV       AX,WORD PTR N

              MOV       CX,5

         M5:  MOV       DX,0

              MOV       BX,10

              DIV       BX

              ADD       DL,30H

              MOV       [DI],DL

              DEC       DI

              LOOP      M5

      ; ============

      ; 输出换行回车

              LEA       DX,LFCR

              MOV       AH,9

              INT       21H

      ; ============

      ; 输出两数的和的10进制串

              LEA       DX,CC

              MOV       AH,9

              INT       21H

              RET

              

           Y  DD        

          CC  DB        10 DUP(' '),10,13,'$'

        LFCR  DB        10,13,'$'

           Z  DD        100000

           N  DW        0

    DISPDXAX  ENDP

        CODE  ENDS

              END       START

C

在一段汇编程序中多次调用另一段程序,用宏指令比用子程序实现占内存空间大,但速度快。

宏调用是通过宏扩展来实现的,宏引用多少次,就相应扩展多少次,所以,引用宏不会缩短目标程序;而子程序代码在目标程序中只出现一次,调用子程序是执行同一程序段,因此,目标程序也得到相应的简化。

扩展资料:

在用一种不熟悉的宏语言进行宏编程时,可以这样做,首先记录下用户想要宏完成什么,然后打开宏文件并尝试理解命令结构如何工作。

也可以修改命令以调整宏。一些宏语言,比如Great Plains 会计软件的 Dexterity 运行时引擎,不能从其它数据源(如由逗号分隔的文本文件)导入数据。这一限制可以通过用更强大的编程语言,如VBA来创建一个计算机程序在此弱编程语言里生成一个特别的宏来解决。

参考资料来源:百度百科-宏命令

程序调用用call指令,调用的子程序必须已经写在程序里。

系统会自动把子程序的返回地址(即调用程序中call指令的下一条指令的地址)存入堆栈,子程序执行后也会自动把堆栈中存的地址取出。

以上就是关于汇编子程序调用及返回全部的内容,包括:汇编子程序调用及返回、汇编语言(用子程序调用来编程的问题!)、汇编语言调用子程序前为什么要push ax,之后再pop ax等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9630352.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存