c - 为什么下面的c函数和asm代码一样

标签 c assembly

谁能解释一下为什么下面的 c 代码等同于 asm 代码?

void arith1(){
    a=(b*10)+(5/(-e));
}

为什么我们要将 b 的值放在 ecx 寄存器中。

ASM代码:

mov  ecx, DWORD PTR _b
imul ecx, 10             ; $1 = b * 10
mov  esi, DWORD PTR _e  
neg  esi                 ; $2 = -e
mov  eax, 5
cdq
idiv esi                 ; $3 = 5 / -e
add  ecx, eax            ; $4 = $1 + $3
mov  DWORD PTR _a, ecx   ; a = $4

最佳答案

mov  ecx, DWORD PTR _b
imul ecx, 10             ; edx:eax = b * 10
mov  esi, DWORD PTR _e  
neg  esi                 ; esi = -e
mov  eax, 5
cdq                      ; edx:eax = 5
idiv esi                 ; eax = 5 / -e
add  ecx, eax            ; ecx = b * 10 + 5 / -e
mov  DWORD PTR _a, ecx   ; store result to a

唯一不直观的部分是 imul 和 idiv 指令组合了 edx 和 eax 寄存器以形成 64 位值。 imul 指令后高 32 位被丢弃,C 不执行溢出检查。需要 cdq 指令(将 double 转换为四精度)在除法之前将 32 位值转换为 64 位值。

关于c - 为什么下面的c函数和asm代码一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8464646/

相关文章:

c - C 库应如何提醒用户错误的输入以及其他介绍库问题

c - 在 C 语言的宏中声明变量,允许尾随分号

c - (C 中的内联汇编)有趣的内存段错误

C语言中用定时器计时

c - 使用 Microsoft Media Foundation 从非文件源解码音频

c - 从列表中删除符合受另一个列表影响的条件的所有节点

assembly - 标签、函数的命名约定

c - 不同语言的切入点

c++ - 为什么编译器内联产生的代码比手动内联慢?

assembly - 指令集仿真背后的基本思想是什么?