初学者小白,关于王爽老师的汇编语言第208页,遇到的问题
divdw那个子程序,div运算是否有争议?
把一个小于4.2949673的10的9次方的数x,
装入(ax+dx)/cx=x/cx=的结果置于两个16位寄存器存商余数没毛病
但小王八的视频代码处理有错误啊,
ax / cx+dx / cx
;注释个人标注不是原视频,代码是
divdw: ;无溢出除法子程序
push ax ;压栈保存ax被除数低位
mov ax,dx ;dx被除数高位推入ax被除数寄存器
mov dx,0 ;dx置零存商余数
div cx ;高位除以除数cx
mov bx,ax ;默认ax的商存入bx=int(h/n)取商,dx=rem(h/n)取余数,
pop ax ;调出低位被除数
div cx ;L/n
mov cx,dx ;余数存入cx
mov dx,bx ;商存入dx
ret
这样做的过程有错误,高位dx的值没错,ax的值也没错
但是除完cx人数,的商和余数处理有错误啊,
误差过大,导致商值偏离太多啊
先计算低位,会比先计算高位的误差要小
可结果还不是真实数,是不要加入一段代码,细节处理
比如and 和jcxz配合处理
第一次计算的余数与第二次被除数的关系啊
求前辈处理
还是我的知识太少哪里误区了能帮忙指出吗,谢谢大家
我是0蛋初学者,没任何计算机语言基础,书里后面的知识还没学,,,,卡这里过不去了,
是不是王爽老师故意把问题留下为以后学习铺垫呢
首先,对于你遇到的问题,我会尽量给出一个较为详细的解答。但是由于时间和字数的限制,无法完整地给出一个包含细节处理的代码示例。希望你能理解。
关于divdw子程序的运算方式和是否有争议,其实并没有明确的错误或争议。它是根据8086处理器的指令集设计的,主要用来进行无溢出除法。在执行div指令时,被除数存在两个寄存器中:高位存储在DX中,低位存储在AX中。除数存储在CX寄存器中。除法完成后,商存储在AX中,余数存储在DX中。
在这个子程序中,先将AX的高位移到DX中,然后将DX和CX一起作为被除数进行除法运算。第一次运算得到的商存储在BX中,余数存储在DX中。接着将之前保存的低位被除数重新装载到AX中,再次进行除法运算,得到的商存储在DX中,余数存储在CX中。最后将结果保存到CX和DX中,并返回。
至于你提到的误差过大的问题,可能是因为除法运算本身存在精度问题。在计算机内部,浮点数除法一般都有一定的误差。这是由于使用二进制表示浮点数时,某些小数无法精确表示而引起的。如果你需要更高的精度,可以考虑使用其他方法来进行除法运算,如乘法逆元来代替除法等。
总之,对于初学者来说,了解div指令的使用方法和注意事项是很重要的。了解如何处理余数和商值的关系也是有帮助的。但是在实际编程中,为了提高精度和减小误差,可能需要额外的处理。
至于你的疑问是否是故意留下的问题,我不能确定。但是对于一本教材来说,可能会故意设计一些让学生思考和探索的问题,以激发学习兴趣和培养解决问题的能力。这也是学习编程的过程中常见的情况,所以不要气馁,继续努力学习,相信你能够理解并解决这个问题的!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2024-2-22 13:32
首先,对于你遇到的问题,我会尽量给出一个较为详细的解答。但是由于时间和字数的限制,无法完整地给出一个 ...
好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答案与您的指点一样,
感谢您的帮助,祝您生活愉快
哈哈谢谢
先继续学,不会再回来翻书不能总这里卡着了 int62 发表于 2024-02-22 13:39
好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答 ...
不客气,很高兴能够帮到你。我祝你在学习编程的道路上一切顺利,不要犯困难时坚持下去。如果你有任何问题,随时都可以来问我。祝你生活愉快,再见!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 int62 发表于 2024-2-22 13:39
好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答案与您的指点一样,
感谢您的帮助,祝您生活愉快
哈 ...
他就是gpt,所以回答一样就很正常 这代码没有问题,只是不太优雅
我也写了一个,用了 xchg bx, ax
这就很优雅,^_^
assume cs:code
code segment
divdw:
push bx
mov bx, ax
mov ax, dx
xor dx, dx
div cx
xchg bx, ax
div cx
mov cx, dx
mov dx, bx
pop bx
ret
start:
mov ax, 4240h
mov dx, 000fh
mov cx, 0ah
call divdw
mov ax, 4c00h
int 21h
code ends
end start
这代码看似没有处理余数,实则已经处理了,只不过处理的非常巧妙,巧妙到没有处理,^_^
因为他就已经在那了,已经不需要处理了
你说的是没有乘65536吗?需要明面上乘吗?
乘65536意味着什么?
左移16位
把这个数字从16位变成32位
而且这个32位数字的低16位全是0
这个全是0的低16位需要保存吗?
高16位不就是左移之前的那个低16位吗
直接保存这个左移之前的16位数字不就可以了?
反正左移之后也还是这个数字
所以,重看代码
然后再提出你的问题
人造人 发表于 2024-2-22 21:03
你好,我现在我学到这里了,可是,我有个问题一直没懂,它这里的解决溢出问题的实质,是将被除数(5937000)处理成(593700),可是,在课程设计1中,最后一组数据,是5937000,,我要怎么做,才能将处理过后的593700,输出到显存时,还原成5937000呢,
页:
[1]