你好,大会社区!目前我是一名工程专业的学生,我试着解决了一些我的家庭作业问题,其中大部分都很简单,但有一个问题困扰了我10个小时。
这个问题要求我创建一个例程,它接收十六进制格式的16位无符号数字使用堆栈并以十进制格式打印数字,以便每行代表每个前缀,例如对于输入'B26 Eh',我们应该得到:
- 45678
- 4567
- 456
- 45
- 4
程序必须实现递归,我们必须通过堆栈提供输入。
我写了下面的代码:
.model small
.data
.stack 100h
.code
START:
; Setting screen data into ES register
MOV AX, 0B800h
MOV ES, AX
; Setting the data segment
MOV AX, @data
MOV DS, AX
; Screen offset
MOV CX, 0d
MOV BX, 340h
; Testing result
MOV AX, 746FH
PUSH AX
CALL numPrefix
; Exit and print both runs
MOV AX, 4C00h
INT 21h
numPrefix PROC
; Save registers
PUSH BP
PUSH DX
MOV BP, SP
MOV AX, [BP+6d]
; Base condition
CMP AX, 0
JE baseCase
; Else, divide the input by 16d to get the quotient and remainder
PUSH CX ; Save print address
mov cx, 10 ; Divisor
xor dx, dx ; Clear dx for the quotient
div cx ; Divide ax by cx, quotient in ax, remainder in dx
POP CX
; Call numPrefix recursively with the quotient
push ax ; Push the quotient onto the stack
call numPrefix
; PRINT LOGIC #################################################################################
; Now we print what we got for each row in the recursion
MOV DH, 2Eh
SUB BX, 0A0h
PUSH BX
PUSH CX
CMP CX, 0d
JE equalZero
printLoop:
; For each row in the recursion, print the appropriate row of numbers
MOV SI, BX
MOV DI, [BX+0A0h]
PUSH AX
MOV AX, ES:[SI]
MOV ES:[DI], AX
POP AX
ADD BX, 1
loop printLoop
equalZero:
POP CX
; Add new member
ADD BX, 1
MOV ES:[BX], DX
POP BX
INC CX
; PRINT LOGIC #################################################################################
; Finish and restore registers
; Also Base case where we only print and not do recursion again
baseCase:
pop DX
pop BP
ret 2
numPrefix ENDP
END START
在我的脑海中的逻辑是相当简单的,我将使用的事实,除以16 h将给予我新的AX(商)和余数(DX)是要打印的。每次我递归地尝试重新调用这个例程,并为递归的每一级使用'print'函数,我复制前一行并将新的余数(DX)添加到新行。
代码不工作,我试着用DOSBOX调试了几个小时,每次我都认为我弄明白了,但最终调试器只是在我回调递归后跳到内存中的随机位置。我已经调试了几个小时了,希望能得到一些帮助。
谢谢你!
编辑:看来我修复了一些问题,我认为递归可以追溯到它的正常位置,但我似乎无法找回DX(余数),因为我从我的递归中追溯,感谢帮助!
最后一个问题:解决了,谢谢大家!
1条答案
按热度按时间jv2fixgn1#
显然我写答案的时候你已经解决了。真有你的!所以它不会浪费,这是我想到的。可能有助于比较解决方案...
你的递归是好的,但与屏幕的交互不是。
例如,
MOV DI, [BX+0A0h]
必须是lea DI, [bx - 160]