我试图在装配中制作一个简单的计算器。我使用TASM(学校政策)。问题是在DT变量中打印用FBSTP命令(协处理器命令)保存的数字。
FBSTP adr - 在地址“adr”处存储位于顶部的值 堆栈(ST(0))作为压缩十进制数(在“adr”中定义) 与DT)。堆栈指针递减。转换 在商店流程中完成。
我调试了程序,当用10分割时,结果被破坏了。例如: 12 * 1 = 12。 res2中的结果是正确的。将它移动到AX后它仍然是正确的但是什么时候 我将它除以10 DX变为8而不是2而不是12它打印18.我也注意到了 12h = 18d,但我不能连接。 LE:如果我在一个单词变量中使用一个简单的整数存储并打印出一个它可以正常工作。
以下是我认为重要的代码部分:
multiplication:
FINIT
FILD x
FILD y
FMUL
FBSTP res2
FWAIT
MOV ax,WORD PTR res2
call write
jmp_line
jmp exit
write PROC NEAR ;my printing proc moves cursor x spaces and starts writing
from back to front
PUSH DX
PUSH AX
PUSH CX
MOV CX,0
CMP AX, 0;check sign
JNS ok_write
NEG AX ;negate if <0
MOV CX,1 ;used to know if number is negative
ok_write:
printspace ;macro that jumps 5 spaces(maximum number length)
;starts printing the number backwards
print_digit:
inc len
;print each digit
MOV DX,0 ;prepare DX for storing the remeinder
DIV CS:ten ;divide AX by 10 so that the last digit of the number is stored
ADD dl,30h ;transform to ascii
PUSH AX ;save AX
MOV ah,02h
INT 21h ;print last digit
printchar 8 ;put cursor over last printed digit
printchar 8 ;move cursor in front of last printed digit
cmp divi,1 ;
JNE not_div
cmp len,1
JNE not_div
printchar '.'
printchar 8
printchar 8
not_div:
POP AX ;retreive AX
CMP AX,0 ;when AX=0 the number is written
JNE print_digit
;/print each digit
CMP CX,1
JNE end_print
printchar '-'
end_print:
POP CX
POP AX
POP DX
RET
write ENDP
非常感谢。
答案 0 :(得分:0)
您在AX中加载BCD号码。 BCD表示二进制编码的十进制。所以每4位实际上是一个十进制值。除以10,也是十进制。但是AX将数字视为十六进制。 如果你试图将12(bcd)除以10(十进制),那么12将被视为十六进制,十进制值为18. 18除以10(十进制)或0Ah确实在十进制18的末尾给出。 如果12是bcd,你只需要从打包的bcd(每个4位是十六进制的十进制编码)转换为unpacked(每个8位代表一个十进制数字)。 为了方便起见:如果AX包含12(bcd),那么你可以和0Fh的AX一起得到它的2,并用0F0h来获得1的结果。 对于数字,您只需添加30h(“0”)。对于帐篷,你需要4比特,并添加30小时(“0”)。 再次:如果您将AX = 12中的压缩bcd转换为AX = 0102中的解压缩BCD并向其添加3030h,则AX将包含12(bcd)的ASCII。 要存储它以在屏幕上打印它,您必须知道低8位将存储在内存中的较低地址中。 因此,使用xchg AH,AL开关AH和AL,因此AX = 3231h并存储在DS中的存储器位置。 对于大于99(bcd)的数字,你应该使用相同的技术来提取数百,数千等.... 我希望这会搞清楚。