如何在汇编中实现 mod 运算符

2024-02-06

我正在学习汇编语言中的除法。根据我正在学习的书,idiv运算的结果放在eax中,余数放在edx中。

书中的一个练习是实现number = result % divisor在装配中。

我本以为这相当于正常的除法运算,除了 edx 是结果。

然而这并没有起作用,edx 返回了看似垃圾的结果。

为什么?如何用汇编实现上述伪代码?


整数模可以通过两种方式实现:

首先通过使用DIV or IDIV,其中余数将被放入EDX,但你需要归零EDX首先,或者引用英特尔:

Operand Size -----------| Dividend | Divisor | Quotient | Remainder
Quadword/doubleword     | EDX:EAX  |  r/m32  |   EAX    |   EDX. 

eg:

eax = eax % 9

当无符号变为:

XOR EDX,EDX ;clear the destinations for outputs. this stops the garbage remainder  
MOV ECX,9
DIV ECX
MOV EAX,EDX

签署后的内容是:

MOV ECX,9
CDQ ;this will clear EDX due to the sign extension
IDIV ECX
MOV EAX,EDX

第二种方法是在使用 2 的幂取模时使用的优​​化,在这种情况下,您AND比二的幂小一,例如:eax = eax % 8变成AND EAX,7.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在汇编中实现 mod 运算符 的相关文章

  • 如何通过查看程序集来判断程序是否使用动态调度

    我在 Reddit 上读过一篇文章Herb Stutter JIT 永远不会像原生一样快 http www reddit com r programming comments rr2dj herb stutter jit will neve
  • 了解带有 pc 偏移的 Cortex-M 组件 LDR

    我正在查看这段 C 代码的反汇编代码 define GPIO PORTF DATA R volatile unsigned long 0x400253FC int main void Initialization code while 1
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • Linux 内核中是否使用了扩展指令集(SSE、MMX)?

    好吧 它们带来 至少应该带来 性能的巨大提升 不是吗 所以 我还没有看到任何 Linux 内核源代码 但很想问 它们是否以某种方式被使用 在这种情况下 对于没有此类指令的系统 必须有一些特殊的 代码上限 SSE 和 MMX 指令集在音频 视
  • 0 和双字 0 有什么区别?

    正如问题所述 有什么区别 例如 mov eax 0 and mov eax dword 0 我一直在使用 cmp 语句 但我无法理解其中的区别 一个是地址 另一个是数值 如前所述 MOV 指令没有区别 对于 CMP 您将有以下区别 qwor
  • MAC-1 汇编递归

    如何在 MAC 1 汇编器中调用递归函数 在 C 中你会做类似的事情 int func int num if num 0 return 1 return num func num 1 我知道如何使用调用函数 CALL 以及如何将参数加载到堆
  • X86 汇编将小写字母转换为大写字母

    实现toUpper函数 将字符串中的小写字母转换 为大写 该函数采用一个参数 char string 字符串是一个 char类型指针 指向字符串的开头 因为C 样式字符串以零结尾 我们不需要取长度 字符串作为另一个参数 我需要帮助开始 我不
  • 如何创建一个扩展为“(x+y*240)*2”这样的表达式的 GNU GAS 宏?

    我正在使用 GAS 为 ARM Linux 构建一个程序 但我想做一些宏以使我的开发更加智能 然后我想知道 我怎样才能为此做一个宏 x y 240 2 were x and y are int 将像这样使用 mov r0 MACRO SHO
  • 本机代码、机器代码和汇编代码有什么区别?

    我对 NET 语言上下文中的机器代码和本机代码感到困惑 它们之间有什么区别 它们是一样的吗 这些术语确实有点令人困惑 因为它们有时使用不一致 机器代码 这是定义最明确的一种 它是使用字节码指令的代码 您的处理器 执行实际工作的物理金属部件
  • 添加饱和 32 位有符号整数内在函数?

    有人可以推荐一种使用 Intel 内在函数 AVX SSE4 添加饱和 32 位有符号整数的快速方法吗 我查看了内在指南并发现 mm256 adds epi16但这似乎只添加 16 位整数 我没有看到 32 位有任何类似的东西 其他电话似乎
  • RISC-V反汇编器与秒杀运行结果不符?

    我已经设置了一个 hello world 程序只是为了测试我的riscv32 unknown elf工具链 spike pk等等虽然我设法使用打印了 hello worldspike isa RV32 pk hello elf 我发现如果我
  • 汇编:使用数据段寄存器(DS)

    目前我正在学习 x86 汇编 因为我喜欢微控制器编程 所以我熟悉汇编 目前我一直在到处寻找这个问题的答案 但似乎找不到它 DS寄存器 我知道它应该指向我程序中的全局数据 但我不知道知道它到底是如何工作的 我正在使用 NASM 在大多数简单的
  • 如果我有一个 8 位值,那么使用 8 位寄存器而不是 16、32 或 64 位寄存器有什么优势吗?

    我读到的 x86 asm 介绍性文献似乎在所有实际场景中都坚持使用 32 位寄存器 eax ebx 等 除了证明 64 位寄存器也存在之外 如果确实提到 16 位寄存器 那也是作为历史注释来解释为什么 32 位寄存器的名称前面有一个 e 编
  • 是否可以调用驻留在 exe 中的非导出函数?

    我想调用驻留在第 3 方 exe 中的函数并获取其结果 好像有should是一种方法 只要我知道函数地址 调用约定等 但我不知道如何 有谁知道我会怎么做 我意识到任何解决方案都是非标准的黑客 但有must成为一种方式 我的非恶意用例 我正在
  • GCC 从 C++ 程序生成的汇编代码中的 .cfi 和 .LFE 是什么?

    我有以下 C 代码 int factorial int n if n 0 return 1 return n factorial n 1 int main void factorial 5 return 0 当我使用 g S Factori
  • 如何在 MOS 6502 的 asm 中创建延迟

    我是 ASM 新手 我正在尝试研究如何为以下代码创建延迟 org 1000 loop inc d021 jmp loop 我想评论已经足够清楚了 每帧更改颜色的代码示例 1 50 秒 sei enable interrupts loop1
  • 尝试理解 printf() 的 gcc 汇编输出

    我正在尝试学习如何理解汇编代码 因此我一直在研究 GCC 的汇编输出以获取一些愚蠢的程序 其中之一只不过是int i 0 我现在或多或少完全理解了其中的代码 最大的困难是理解散布的 GAS 指令 无论如何 我向前迈了一步并添加了printf
  • 在 x86 汇编语言中获取文件大小的简单方法

    假设我已经在汇编中打开了一个文件 并且在寄存器 eax 中有该文件的文件句柄 我将如何获取文件的大小 以便为其分配足够的缓冲区空间 我在这里研究了另一个讨论 建议使用sys fstat 28 系统调用来获取文件统计信息但无法实现它 My a
  • __stack_chk_fail_local 和 -fno-stack-protector - 如何让它工作?

    Update 我刚刚发现问题出在我的项目 libxml2 中包含的预构建库上 它是在启用堆栈保护的情况下构建的 因此依赖于 stack chk fail local方法 我现在已经重建了该库 fno stack protector也是 一切
  • 查找用户输入中的第一个和最后一个大写字母

    输入将从 a z 或 A Z 中获取 并且输入以星号结束 我们需要将输入字符的第一个和最后一个大写字母作为输出 另外 我们应该显示每次输入的内容 注意 我们逐个字符地获取输入 而不是作为字符串 测试用例1 输入 aAbCcP 输出 AP 测

随机推荐