鱼C论坛

 找回密码
 立即注册
查看: 443|回复: 4

关于公式x/n=int(h/n)*65536+[rem(h/n)*65536+L]/N

[复制链接]
发表于 2024-3-1 22:35:36 | 显示全部楼层 |阅读模式

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

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

x
;                        公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
                        mov ax,ds:[si];        L  ax=9768
                        add si,2
                        mov dx,ds:[si];H   dx=005a
                        push ax
                        mov ax,dx;H > L    ax=005a
                        xor dx,dx ;高位置零  dx=0
                        div bx    ;求余数  9
                        mul 65536     >>>>>>>65536转换成16进制后,为10000H,,这不也是溢出了吗,????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-3-1 22:36:13 | 显示全部楼层
首先,我们需要了解一下这段代码的意图。根据公式 `X/N=int(H/N)*65536/N`,代码的目标是计算整数除法的结果,并将结果乘以65536。

让我们来看一下代码的具体实现:
mov ax, ds: ; L  ax=9768
    add si, 2
    mov dx, ds: ; H   dx=005a
    push ax
    mov ax, dx ; H > L    ax=005a
    xor dx, dx ; 高位置零  dx=0
    div bx ; 求余数  9
    mul 65536 ; 乘以65536

在这段代码中,`ax` 寄存器保存了L的值,`dx` 寄存器保存了H的值。

接下来,代码使用 `div` 指令进行除法运算,它将 `ax` 寄存器中的数除以 `bx` 寄存器中的数,并将商保存在 `ax` 中,余数保存在 `dx` 中。在这里,`bx` 寄存器没有被初始化,所以除法运算可能会产生未知的结果。

接着,代码使用 `mul` 指令将 `ax` 寄存器中的值乘以65536,乘积将保存在 `dx:ax` 寄存器对中(高位在 `dx`,低位在 `ax`)。

至于你提到的溢出问题,我们需要注意一个细节:在 x86 架构下,`mul` 指令会将结果截断到寄存器的位数上。在这里,`ax` 寄存器是16位的,所以乘法的结果也会是16位的。所以,即使乘积超过了16位,它也不会溢出,只是结果可能不准确。

如果你想要得到一个精确的结果,可以使用更大的寄存器,比如 `eax` 或 `r/m64`,这样就可以保证结果不溢出。

以下是修正后的代码示例:
mov eax, ds: ; L  eax=9768
    add esi, 2
    mov edx, ds: ; H   edx=005a
    push eax
    mov eax, edx ; H > L    eax=005a
    xor edx, edx ; 高位置零  edx=0
    div ebx ; 求余数  9
    mov ecx, 65536 ; 将常数 65536 存入 ecx
    mul ecx ; 乘以 65536

这样,你就可以确保计算结果不会溢出,并且得到预期的结果。

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

使用道具 举报

 楼主| 发表于 2024-3-1 22:43:28 | 显示全部楼层
FishC 发表于 2024-3-1 22:36
首先,我们需要了解一下这段代码的意图。根据公式 `X/N=int(H/N)*65536/N`,代码的目标是计算整数除法的结 ...

可是我现在学的是16位汇编,,书上给的是这个公式,怎么破?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-1 22:43:53 | 显示全部楼层
liuming1978 发表于 2024-03-01 22:43
可是我现在学的是16位汇编,,书上给的是这个公式,怎 ...


如果你正在学习16位汇编,并且书上给出的公式是 `X/N=int(H/N)*65536/N`,那么我们可以继续使用16位寄存器来实现这个公式。在这种情况下,我们可以将 `ax` 寄存器用作商的存储器,将 `dx` 寄存器用作余数的存储器。以下是修正后的代码示例:
mov ax, ds: ; L  ax=9768
add si, 2
mov dx, ds: ; H   dx=005a
xor bx, bx ; 将 bx 寄存器清零,以便用作除数
mov bl, N ; 将除数 N 存入低字节
div bx ; 进行除法运算,商存入 ax,余数存入 dx
imul ax, 65536 ; 将 ax 的值乘以 65536
idiv bx ; 进行除法运算,结果存入 ax(商)中

请注意,这里假设 `N` 是一个已知的常量,你需要将其替换为具体的数值。另外,由于我们要用到 `bx` 寄存器作为除数,所以需要保证它的值是正确的。你可以根据实际情况进行修正。

希望这样能解决你的问题,如果还有疑问,请随时提问!

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

使用道具 举报

发表于 2024-3-2 21:26:27 | 显示全部楼层
乘以65536之后肯定溢出了,你为什么要乘以65536 ?
乘以65536意味着什么?
举个例子
0x1234是一个16位的值,给这个值乘以65536等于多少?
0x1234 * 65536 = 0x12340000
有问题吗?有什么问题?
乘以65536之后,这个16位的值就变成32位的值了
这个高16位的值还是0x1234,低16位全是0
有问题吗?有什么问题?
乘以65536之后的低16位全是0,你需要浪费一个16位的寄存器来保存这个全0的低16位吗?
高16位就是乘65536之前的那个数字
0x1234乘以65536之后的高16位还是0x1234
所以,你乘65536做什么?有必要乘这个65536吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-21 23:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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