Assembly 汇编x8086中的乘法和除法练习

Assembly 汇编x8086中的乘法和除法练习,assembly,ascii,converter,division,multiplication,Assembly,Ascii,Converter,Division,Multiplication,几天前我刚开始学习组装,看来我遇到了困难。我有一个问题,我必须在汇编中生成一个接受整数输入(celcius)并将其转换为华氏温度的程序 这是我的密码: org 100h jmp compare var1 db 0 ans1 db ? num1 db ? num2 db ? ex1 db ? ex2 db ? compare: cmp var1,0 je start jne move move: mov bl,var1 mov num1,bl jmp digits start:

几天前我刚开始学习组装,看来我遇到了困难。我有一个问题,我必须在汇编中生成一个接受整数输入(celcius)并将其转换为华氏温度的程序

这是我的密码:

org 100h

jmp compare 
var1 db 0 
ans1 db ?
num1 db ? 
num2 db ?
ex1 db ?
ex2 db ?

compare:
cmp var1,0
je start
jne move

move:
mov bl,var1
mov num1,bl
jmp digits

start:


mov ah,01h
int 21h
mov num1,al
cmp num1,0dh
jne digits
je convert

digits:



mov ah,01h
int 21h
cmp al,0dh
je revert
mov num2,al
jne proceed


proceed:
sub num1,48
mov cl,num1
mov al,10
imul cl
mov num1,al

sub num2,48


mov bl,num2
add num1,bl
mov bl,num1
mov var1,bl
jmp compare

revert:
cmp num2,0 ;also added this one too recently
jne c1
sub num1,48
c1:
mov bl,num1
mov var1,bl
jmp convert



convert:



mov cl, var1
mov al, 9
imul cl
mov cl, 5
idiv cl
add al, 32
mov ans1, al                
mov bl,ans1

mov dl,0    ;i recently added this for convertion
mov al,ans1
mov bl,10
div bl
mov ex1,al
mov ex2,ah

adc ex1,48
adc ex2,48





print:
mov ah,02h
mov dl,10
int 21h
mov ah,02h
mov dl,13
int 21h

mov ah,02h
mov dl,ans1
int 21h

mov ah,02h ;print the converted values
mov dl,ex1
int 21h
mov ah,02h
mov dl,ex2
int 21h
ret
我曾经输入15,这将导致“;”在ascii中是59。 我需要帮助转换ascii码;当我输入更多时,输入小数 超过2个数字,表示溢出除法。我该如何解决这个问题?提前谢谢

编辑:我最近添加了转换代码。它现在可以工作了,但是如果我在输入中输入超过“20”,那么输出就会出错。我使用了奥尔登的想法(多谢老兄!)修改答案并分别转换和打印。我现在还在做这个,我还在挠头哈哈。这么多的错误哈哈


再次编辑:这太奇怪了。我的程序只能转换以5结尾的数字。它只能正确转换5、15、25和35。这太奇怪了,其他的都是乱七八糟的输出。有人能告诉我为什么会发生这种情况吗?

这需要比你想象的更多的工作。还有几种方法可以做到这一点。基本上,您想要的是获得每个十进制位置的值,然后打印
结果+48
(48是ascii 0)

例如,假设您的输入是15。您要打印
1
5
。您可以通过执行
15 mod 10
来获取
5
。然后将15除以10。此结果为
1
<代码>1 mod 10导致
1
。您可以将这些值推送到堆栈上,直到您的
值mod 10
等于零。我的组件生锈了,但这应该是一个功能模块:

modTen:
    push   bp
    mov    bp, sp
    push   bx
    mov    ax, word [bp+4]
    mov    bx, ax
    cwd
    idiv   10
    imul   10
    sub    bx, ax
    mov    ax, bx
    pop    bx
    mov    sp, bp
    pop    bp
    ret
我使用的是GCC风格的调用者/被调用者假设,但是您可以做任何您想做的事情。接下来,您需要一个包含以下步骤的循环

push your parameter
call modTen
pop your parameter (or increment your SP)
push your result
increment a register to keep track of number of digits
divide your original value by 10
check if the result is zero. 
    If not, go back to the start of the loop. 
    If so, start popping your values and printing them.
更新:
SP
表示堆栈指针。它指向存储在堆栈上的最后一个值。当
push
时,
SP
递减,引用寄存器中的值被推送到
SP
所指向的位置
pop
SP
指向堆栈外的值弹出到寄存器中,然后递增
SP
。(如果你想装一个弹匣,你可以将子弹推入弹匣,然后将其弹出。这是一个先进、后进或堆叠的结构)

BP
代表基指针,指向标记当前函数正在使用的堆栈起点的位置。例如,在
modTen
中,调用函数时,它会保存旧函数中的基指针,将当前堆栈指针移动到基指针中,然后将其用作附近所有其他值(如函数的参数)的引用。这样做的目的是,当函数执行时,它需要堆栈空间来存储变量。当堆栈指针在周围移动时,您将丢失对象所在的位置(虽然您可以在不使用基指针的情况下完全正确)

在汇编语言中编写代码时,可以方便地将代码分成函数,并设置一些假设,这样当其他人使用您的代码时,或者您在将来某个时候重新使用代码时,您就不需要重新阅读所有代码来使其正常工作。汇编通常很难理解,因为作者的意图并不明显。8086汇编的惯例是将函数的参数按相反顺序推送到堆栈上。然后使用
call
跳转到函数。调用将下一条指令的位置(返回地址)推送到堆栈上。然后被调用函数(或被调用方)通过按下前一个函数的基指针来保存它。然后将
SP
复制到
BP
中,
BP
的值用于引用变量。被调用方还将在使用之前保存所有已使用的寄存器,除了
AX
,然后在事后恢复它们
AX
用于返回值,因此调用方必须在调用之前保存其中的内容(如果您想保留它)。当函数执行时,堆栈将如下所示

                              ....
function's second argument -> XXXX
function's first argument  -> XXXX
return address             -> XXXX
BP points here             -> XXXX
  Also, saved last BP
some variable              -> XXXX
                              ....
SP points here             -> XXXX
  and another variable
                              ....
很明显,您对x86体系结构不是很熟悉,这在编写x86汇编时非常重要。例如,您可能知道也可能不知道x86使用段以及指针寄存器来计算地址。随着您在x86汇编方面的经验越来越丰富,这很可能会让您绊倒。我强烈建议找一本书或在线资源,详细介绍8086体系结构。如果你这样做了,你将做好准备,长出你的脖子胡子,像1980年那样把代码拼凑在一起

此外,如果您正在使用某种linux或unix环境,您已经拥有世界上最好的汇编学习资源。 使用
objdump-S a.out
查看已编译可执行文件的程序集。如果您使用-g编译,那么它将向您显示哪段代码与哪条汇编指令相匹配。非常整洁。(顺便说一句,这是假设您正在使用gcc)此外,我从未使用过它,但该用户有一个用于gcc编译8086兼容16位指令的补丁


祝你好运

是的,那真是太棒了!但我似乎不明白怎么做。我知道你可以把它改成10,然后把它的余数改成数字,然后打印出来。但是我不明白怎么做的方法。对不起,我真的是一个组装新手,我仍然不明白那些sp-bp和push-and-pop是什么意思。现在我只是把答案除以10,得到了余数之类的,然后设法把数字分开并打印出来。比如,如果我输入15,结果是“;”,我使用了mod和类似的东西,得到了“59”,这是正确的,但是如果