IA-32装配部

发布于 2024-12-04 07:10:35 字数 454 浏览 3 评论 0原文

有人可以向我解释以下汇编代码片段:

mydiv:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %edx  ; get x
        movl    %edx, %eax
        sarl    $31, %edx      ; divide by y
        idivl   12(%ebp)       ; return %eax
        popl    %ebp
        ret

这相当于以下 C 函数:

int mydiv( int x, int y )
{
    return x / y;
}

我无法理解的部分是 sarl 指令:为什么需要转移 edx

Can somebody explain to me the following snippet of assembly:

mydiv:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %edx  ; get x
        movl    %edx, %eax
        sarl    $31, %edx      ; divide by y
        idivl   12(%ebp)       ; return %eax
        popl    %ebp
        ret

This is the equivalent to the following C function:

int mydiv( int x, int y )
{
    return x / y;
}

The part which I'm having trouble understanding is the sarl instruction: why do you need to shift edx?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浮生未歇 2024-12-11 07:10:36

这是符号扩展

idivl 有一个 64 位参数 (edx:eax),因此您需要根据 eax 的 msb 确保 MSB 包含正确的符号位

因此,如果eax为正,则其msb将为0,例如5 -> 0000 ... 0101。如果它是负数,则 MSB 将为 1,例如 -5 -> 1111 ... 1011sarl 执行算术右移,因此 edx 将是 0000 ... 00001111 ... 1111代码>.

It's sign extending.

idivl has a 64-bit argument (edx:eax), so you need to ensure that the MSB contains the correct sign bits, based on the msb of eax.

So if eax is positive, it's msb will be 0, e.g. 5 -> 0000 ... 0101. If it's negative it's msb will be 1, e.g. -5 -> 1111 ... 1011. sarl performs an arithmetic right-shift, so edx will either be 0000 ... 0000 or 1111 ... 1111.

甜心 2024-12-11 07:10:36

值得注意的是,有一条专门的指令根据EAX的符号位向EDX填充0或1。

cdq

或者在 AT&T 语法中,cltd(长到双宽?),但 GNU 汇编器接受任一助记符。
idiv之前使用它;它隐式读取 EAX 并写入 EDX,将 EAX 符号扩展为 EDX:EAX 作为被除数。

div 之前,通常您希望通过 xor %edx,%edx 将 EAX 零扩展为 EDX:EAX。

还有其他可用宽度,例如用于将 AL 符号扩展为 AX 的 cbw,以及用于将 RAX 符号扩展为 RDX:RAX 的 cqocltq 在汇编中做什么? 有一个 AT&T 语法和 Intel 手册中的助记符之间的等效表。

It is worth noting that there is a dedicated instruction to fill EDX with 0s or 1s based on the sign bit of EAX.

cdq

Or in AT&T syntax, cltd (long to double-width?), but the GNU assembler accepts either mnemonic).
Use this before idiv; it implicitly reads EAX and writes EDX, sign-extending EAX into EDX:EAX as the dividend.

Before div, normally you want xor %edx,%edx to zero-extend EAX into EDX:EAX.

There are other widths available, like cbw to sign-extend AL into AX, and cqo to sign-extend RAX into RDX:RAX. What does cltq do in assembly? has an equivalence table between AT&T syntax and the mnemonics in Intel's manuals.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文