鱼C论坛

 找回密码
 立即注册
查看: 480|回复: 6

[争议讨论] 初学者小白,关于王爽老师的汇编语言第208页,遇到的问题

[复制链接]
发表于 2024-2-22 13:31:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
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蛋初学者,没任何计算机语言基础,书里后面的知识还没学,,,,卡这里过不去了,
是不是王爽老师故意把问题留下为以后学习铺垫呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-2-22 13:32:34 | 显示全部楼层
首先,对于你遇到的问题,我会尽量给出一个较为详细的解答。但是由于时间和字数的限制,无法完整地给出一个包含细节处理的代码示例。希望你能理解。

关于divdw子程序的运算方式和是否有争议,其实并没有明确的错误或争议。它是根据8086处理器的指令集设计的,主要用来进行无溢出除法。在执行div指令时,被除数存在两个寄存器中:高位存储在DX中,低位存储在AX中。除数存储在CX寄存器中。除法完成后,商存储在AX中,余数存储在DX中。

在这个子程序中,先将AX的高位移到DX中,然后将DX和CX一起作为被除数进行除法运算。第一次运算得到的商存储在BX中,余数存储在DX中。接着将之前保存的低位被除数重新装载到AX中,再次进行除法运算,得到的商存储在DX中,余数存储在CX中。最后将结果保存到CX和DX中,并返回。

至于你提到的误差过大的问题,可能是因为除法运算本身存在精度问题。在计算机内部,浮点数除法一般都有一定的误差。这是由于使用二进制表示浮点数时,某些小数无法精确表示而引起的。如果你需要更高的精度,可以考虑使用其他方法来进行除法运算,如乘法逆元来代替除法等。

总之,对于初学者来说,了解div指令的使用方法和注意事项是很重要的。了解如何处理余数和商值的关系也是有帮助的。但是在实际编程中,为了提高精度和减小误差,可能需要额外的处理。

至于你的疑问是否是故意留下的问题,我不能确定。但是对于一本教材来说,可能会故意设计一些让学生思考和探索的问题,以激发学习兴趣和培养解决问题的能力。这也是学习编程的过程中常见的情况,所以不要气馁,继续努力学习,相信你能够理解并解决这个问题的!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2024-2-22 13:39:14 | 显示全部楼层
FishC 发表于 2024-2-22 13:32
首先,对于你遇到的问题,我会尽量给出一个较为详细的解答。但是由于时间和字数的限制,无法完整地给出一个 ...

好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答案与您的指点一样,
感谢您的帮助,祝您生活愉快
哈哈谢谢
先继续学,不会再回来翻书不能总这里卡着了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-2-22 13:39:27 | 显示全部楼层
int62 发表于 2024-02-22 13:39
好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答 ...


不客气,很高兴能够帮到你。我祝你在学习编程的道路上一切顺利,不要犯困难时坚持下去。如果你有任何问题,随时都可以来问我。祝你生活愉快,再见!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-2-22 14:07:00 | 显示全部楼层
int62 发表于 2024-2-22 13:39
好的前辈,谢谢解惑明白了,也在chatgpt里问了很多次答案与您的指点一样,
感谢您的帮助,祝您生活愉快
哈 ...

他就是gpt,所以回答一样就很正常
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-2-22 21:03:23 | 显示全部楼层
这代码没有问题,只是不太优雅
我也写了一个,用了 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位数字不就可以了?
反正左移之后也还是这个数字

所以,重看代码
然后再提出你的问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-2 00:34:28 | 显示全部楼层

你好,我现在我学到这里了,可是,我有个问题一直没懂,它这里的解决溢出问题的实质,是将被除数(5937000)处理成(593700),可是,在课程设计1中,最后一组数据,是5937000,,我要怎么做,才能将处理过后的593700,输出到显存时,还原成5937000呢,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 09:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表