装配8088 Print AX,BX,AH,AL,BH,BL

时间:2013-04-28 20:57:23

标签: assembly x86 x86-16

我正在研究我的一些课程,并且我遇到了一个让我无法进步的问题。

在第10,14和16行的下面代码中,我需要将相应的值打印到注释的状态。目前,我使用较低的testPrint函数打印出AXBXAHALBH的天气值。 ,BL。 我的问题是,当我尝试在第10行打印出vaules,并使用相同的函数在第14行打印出值时,第14行的值被弄乱并显示不正确答案的内容。当我让程序执行所有适当的功能,如ADDMUL等,并在最后打印出来,它完美地工作。

我也只能使用其中一个测试打印功能,因为如果我尝试同时使用这两个功能,数字就会搞乱。

我正在使用8088汇编程序。

在调用每个打印功能后,我是否遗漏了一些东西?任何人都可以向我展示或告诉我我需要做些什么才能朝着正确的方向前进?

非常感谢你!

This is the code:

_EXIT = 1       ! 1
_PRINTF = 127       ! 2
.SECT .TEXT         ! 3
    start:          ! 4 
MOV AX, 514         ! 5 AX = 514
MOV BX, 2       ! 6 BX = 2

firstOutput:        ! 7output original values of AX and BX
PUSH BX         ! 8
PUSH AX         ! 9
            ! 10 PRINT AX AND BX HERE (SHOULD BE 514,2)

secondOutput:           ! 11 BH = BH + BL; AH= AH - AL
ADDB BH, BL     ! 12
SUBB AH, AL     ! 13
            ! 14 PRINT AX AND BX HERE (SHOULD BE 2, 514)

thirdOutput:        ! 15 MULTIPLY AX AND BX
MUL BX          ! 16
            ! 17 PRINT AH, AL, BH, BL


!testPrint: !THIS WILL PRINT AX AND BX
!PUSH BX
!PUSH AX
!PUSH print
!PUSH _PRINTF
!SYS

testprintall: ! THIS WILL PRINT AH, AL, BH, BL
MOV CX, 0           ! 
MOVB CL, BL         ! 
PUSH CX             ! 
MOVB CL, BH         ! 
PUSH CX             ! 
MOVB CL, AL         ! 
PUSH CX             ! 
MOVB CL, AH         ! 
PUSH CX             ! 
PUSH printahalbhbl  ! 
PUSH _PRINTF        ! 
SYS !

exit:                   ! Exit 
PUSH 0              ! 
PUSH _EXIT          ! 
SYS                 !

 .SECT .DATA            ! 
 print:                 ! 
 .ASCIZ "AX:%d, BX:%d\n" !  
 .SECT .BSS                 ! 

 printahalbhbl:             ! 
 .ASCIZ "AH:%d, AL:%d, BH:%d, BL:%d\n" !
 .SECT .BSS                 !

1 个答案:

答案 0 :(得分:2)

这里缺少两件事:

首先保存允许_printf更改的所有寄存器。 AX就是其中之一。 其次是通话结束后清理堆栈。通常,被调用的函数不知道调用者已经在堆栈上放了多少个参数,因此这通常是调用者的责任。

  push ax  ;; or even pusha
  push bx  ;; 

  push ax
  push bx
  call xxx
  pop  ax   ;; dummy pop to clean the stack
  pop  ax   ;; stack cleaning

  pop  bx   ;; restore BX
  pop  ax   ;; restore ax

因为保存bp需要每个功能,所以在通过

调用后还可以恢复堆栈
  push bp
  mov bp, sp

  push ax ; arguments
  push bx ;
  call xxx       ;; 

  mov sp, bp
  pop bp

或在整个系统中使用此本地堆栈帧概念时:

  mov [bp - xyz ], sp;   // save current stack pointer at a fixed place
  push cx ; // push a lot of arguments
  call zyx
  mov sp, [bp - xyz]     // restore stack pointer