nasm idiv 负值

Posted

技术标签:

【中文标题】nasm idiv 负值【英文标题】:nasm idiv a negative value 【发布时间】:2022-01-23 20:43:38 【问题描述】:

试图将一个正数除以一个负数。

目前我的程序会正确划分,我可以正确访问余数。

但是当我输入一个正数除以一个负值时,它根本不会除。

我知道有一种“符号扩展”的方法,它会正确划分。就是看不懂说明书

movsss $imm/%reg %reg/mem 移动,符号扩展 231 movzss $imm/%reg %reg/mem 移动,零扩展

当然是att语法,我需要intel语法

这是我的代码

xor rdx, rdx
mov rax, [input]
mov rcx, [input2]
idiv rcx

关于如何除以负数的想法?

【问题讨论】:

在做了一些研究之后,我还发现了一个指令“cdq”可能会这样做,但还没有奏效 【参考方案1】:

如果除数是有符号的 64 位值,则无需对其进行任何处理。同样,如果被除数是带符号的 128 位值,则无需对其执行任何操作,只需将其前 64 位加载到rdx,将低 64 位加载到rax

现在,如果任何数字已签名但比idiv 预期的短,您需要对该数字进行签名扩展。符号扩展非常简单。您只需用数字的最高有效位(符号位)填充空位。对于非负数,你用 0 填充该空间,对于负数,你用 1 填充它。有一些可用的指令可以对累加器中当前保存的值进行符号扩展。它们是:cbwcwdecdqecwdcdqcqo。最后三个符号扩展为dx/edx/rdx。您很可能需要cqo 而不是xor rdx, rdx,如下所示:

mov rax, [input]
cqo ; sign extends rax into rdx:rax
mov rcx, [input2]
idiv rcx

至于'但是当我输入一个正数除以一个负值时,它根本不会除',不可能。它要么进行除法,要么调用除法异常(除以 0 或溢出),没有第三种选择。

【讨论】:

cqo 工作了!!!,我尝试了一段时间 cdq,但它没有工作,你能不能给我指出你用来解决这个问题的来源? 在本文档中(来自 amd.com):AMD64 架构程序员手册第 3 卷:通用和系统说明。 @user1050632 因为已经有cwd(将字转换为双字)和cdq(将双字转换为四字),所以可以期望找到像cqo(转换quad 到 oct 字)或类似名称。

以上是关于nasm idiv 负值的主要内容,如果未能解决你的问题,请参考以下文章

nasm 使用总结

Nasm汇编编译器

从 NASM 到 GAS 的翻译

从 NASM 到 GAS 的翻译

归并排序分段故障 NASM

GCC 和 NASM 链接到外部库