Divide Signed Integer By 2 编译为复杂的汇编输出,而不仅仅是一个移位 [英] Divide Signed Integer By 2 compiles to complex assembly output, not just a shift

查看:29
本文介绍了Divide Signed Integer By 2 编译为复杂的汇编输出,而不仅仅是一个移位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个C函数;

int triangle(int width, int height)
{
    return (width * height) / 2;
}

当使用 gcc (gcc -m32 -g -c test.c) 编译时会产生以下程序集 (objdump -d -M intel -S test.o).

When compiled with gcc (gcc -m32 -g -c test.c) produces following assembly (objdump -d -M intel -S test.o).

test.o:     file format elf32-i386


Disassembly of section .text:

00000000 <triangle>:

int triangle(int width, int height)
{
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
    return (width * height) / 2;
   3:   8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
   6:   0f af 45 0c             imul   eax,DWORD PTR [ebp+0xc]
   a:   89 c2                   mov    edx,eax
   c:   c1 ea 1f                shr    edx,0x1f
   f:   01 d0                   add    eax,edx
  11:   d1 f8                   sar    eax,1
  13:   5d                      pop    ebp
  14:   c3                      ret    

我已经知道将整数 n 位右移会将其除以 2^n.然而,根据上面的输出,有符号整数似乎被区别对待(这当然是有道理的).如果我正确读取汇编输出,则在移位之前将整数的符号位添加到自身.

I already know that shifting an integer n bit to right divides it by 2^n. However, according to above output, signed integers seems to be treated differently (which, of course, make sense). If I am reading assembly output correctly, sign bit of the integer added to itself before it is shifted.

在右移之前将整数的符号位加到自身上的目的是什么?

What is the purpose of adding sign bit of the integer to itself before right shifting?

推荐答案

它是为负数获得正确的向零舍入"结果.通过将舍入向负无穷大进行除法,因此与 C 除法运算符的预期结果相比,负数将产生不同的结果.

It is to get the correct "rounding towards zero" result for negative numbers. Division by shifting rounds towards negative infinity, so negative numbers will have a different result compared to the expected result of the C division operator.

一个例子是 -1:右移 1 仍然得到 -1,但 C 运算符 /2 得到 0.

An example is -1: shifting right by 1 gives -1 still, but the C operator / 2 gives 0.

所以额外的代码是对这种效果的修正.如果您不需要它,请使用无符号或显式移位(但第二个选项不太便携).

So the extra code is a correction for this effect. If you don't need that, use unsigned or an explicit shift (but the second option is less portable).

这篇关于Divide Signed Integer By 2 编译为复杂的汇编输出,而不仅仅是一个移位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆