2016-03-14 67 views
0

我在cygwin下的Windows 7机器上以32位模式使用GCC。我有以下功能:GCC和乘法指令

unsigned f1(unsigned x, unsigned y) 
    { 
     return x*y; 
    } 

我想要的代码做一个无符号乘法,因此我希望它产生的MUL指令,而不是IMUL指令。我编译程序 用下面的命令:

gcc -m32 -S t4.c 

生成的汇编代码是:

 .file "t4.c" 
    .text 
    .globl _f1 
    .def _f1; .scl 2; .type 32; .endef 
_f1: 
    pushl %ebp 
    movl %esp, %ebp 
    movl 8(%ebp), %eax 
    imull 12(%ebp), %eax 
    popl %ebp 
    ret 
    .ident "GCC: (GNU) 4.8.2" 

我相信,生成的代码中有错误的乘法指令,但我觉得很难相信海湾合作委员会有这样一个简单的错误。请给出意见。

+1

代码有什么问题?它不工作或产生错误的结果? – Olaf

+2

由于您对精确选择汇编指令非常关注,您必须阅读'Intel®64和IA-32架构软件开发人员手册',特别是'IMUL-Signed Multiply:[...] 2和3 - 操作数形式也可以与无符号操作数一起使用,因为产品 的下半部分是相同的,无论操作数是有符号还是无符号。但是,CF和OF标志不能用来确定结果的上半部分是否为非零。 – EOF

+1

[无论有符号还是无符号乘法,下半部结果都是相同的](http://stackoverflow.com/q/14063599/995714)。这是2的补充之一 –

回答

6

编译器依赖于“as-if”规则:没有标准符合的程序可以检测到该程序执行的操作与程序执行的操作之间的区别,因为结果的最低32位对于这两个指令都是相同的。

+0

这就是为什么英特尔不会制作'mul'的2和3操作数版本的原因。如果有用处,它就会存在。 –

+0

@PeterCordes:我想知道是否有任何理由,他们没有将这样的“指令”定义为与“imul”形式具有相同的机器指令,就像他们对一些以关系命名的条件分支所做的那样在一个比较目的地和来源之间,但实际上只是检查进位标志。 – supercat

+0

@supercat:最近的一个问题最终揭示了为什么具有多个显式操作数的'mul'不仅仅是'imul'的同义词:[imul r,r仍然具有用于设置CF和OF的签名语义](http:/ /stackoverflow.com/questions/38253541/c-unsigned-long-long-and-imulq/38254324#38254324)。此外,它的imm8格式使用符号扩展,而不是零扩展。 –