当前位置: 代码迷 >> 汇编语言 >> ,关于堆栈传递参数的一段代码
  详细解决方案

,关于堆栈传递参数的一段代码

热度:1011   发布时间:2013-02-26 00:00:00.0
请教各位,关于堆栈传递参数的一段代码。
程序说明:编制一个子程序把一个16位二进制用十六进制形式在屏幕上显示出来,采用堆栈方法传递这个16位二进制数,并用一个主程序验证它。

代码如下:
                ;   数据段
DSEG         SEGMENT ;定义数据段
      STRING DB   0DH,0AH, "Hex   output   :   ",0DH,0AH, "$ "
DSEG         ENDS
                ;   堆栈段
SSEG         SEGMENT   STACK       ;定义堆栈段
                DB             100H         DUP(?)   ;设置堆栈段大小为100H
SSEG         ENDS
                ;   代码段
CSEG         SEGMENT ;定义代码段
                ASSUME     CS:CSEG,   DS:DSEG,   SS:SSEG       ;关联段寄存器
START:                 ;主程序入口点
MAIN PROC
MOV   AX,DSEG
MOV   DS,AX
MOV   CH,2
MOV   BX,1111000010100101B     ;16进制为F0A5
PUSH   BX
CALL   BTOH
ADD   SP,4
MOV   CL,8
ROL   BX,CL
PUSH   BX
CALL   BTOH
CALL   EXIT
MAIN   endp

BTOH PROC
PUSH   BP
PUSH   CX
PUSH   BX
MOV   CH,2
MOV   BP,SP
MOV   BL,BYTE   PTR[BP+4]
AGAIN:
MOV   CL,4
ROL   BL,CL
MOV   AL,BL
AND   AL,0FH
OR   AL,30H
CMP   AL,3AH
JB   NEXT
ADD   AL,07H
NEXT:
MOV   DL,AL
MOV   AH,2
INT   21H
DEC   CH
JNZ   AGAIN
POP   BX
POP   CX
POP   BP
ret
BTOH   endp
                ;   退出   DOS
EXIT:
                MOV   AH,1
                INT   21H
                MOV   AX,   4C00H     ;返回DOS系统
                INT   21H
CSEG         ENDS
END   START             ;   程序结束

问题在于结果不是F0A5。
初步怀疑是堆栈传递参数,但仍未解决,请各位指点一下。
谢谢!

------解决方案--------------------------------------------------------
MOV BP,SP 应该放在紧接 push bp 指令后吧. 堆栈分析很简单的, 因为这时:
[bp][0]: 刚才压栈的 bp
[bp][2]: 子程返回地址. 如果子程是 far 类型的话, 这里要占用两个 word 以存放 cs:ip
[bp][4]: 调用子程前压栈的参数

如果 mov bp, sp 指令放在了 push cx 和 push bx 指令之后的话, 堆栈就成了:
[bp][0]: 刚才压栈的 bx
[bp][2]: 刚才压栈的 cx
[bp][4]: 子程开始时压栈的 bp
[bp][6]: 子程返回地址
[bp][8]: 这里才识调用子程前压栈的参数
  相关解决方案