我有以下C/C代码(编译器浏览器链接):
void update_mul(int *x, int *amount) {
*x *= *amount;
}
void update_add(int *x, int *amount) {
*x += *amount;
}
在clang和gcc编译为C或至少启用了-O1
的情况下,上述代码转换为此程序集:
update_mul: # @update_mul
mov eax, dword ptr [rdi]
imul eax, dword ptr [rsi]
mov dword ptr [rdi], eax
ret
update_add: # @update_add
mov eax, dword ptr [rsi]
add dword ptr [rdi], eax
ret
对于add,它似乎在做一些类似于:
register = *amount;
*x += register;
但是对于乘法,它正在做:
register = *x;
register *= *amount;
*x = register;
为什么乘法在加法上需要额外的指令,或者它不是必需的,只是更快?
IA-32体系结构规范(替代单页链接)表明,在目标(第一个参数)是内存操作数的情况下,IMUL根本没有编码:
Encoding | Meaning
IMUL r/m8* | AX ← AL ∗ r/m byte.
IMUL r/m16 | DX:AX ← AX ∗ r/m word.
IMUL r/m32 | EDX:EAX ← EAX ∗ r/m32.
IMUL r/m64 | RDX:RAX ← RAX ∗ r/m64.
IMUL r16, r/m16 | word register ← word register ∗ r/m16.
IMUL r32, r/m32 | doubleword register ← doubleword register ∗ r/m32.
IMUL r64, r/m64 | Quadword register ← Quadword register ∗ r/m64.
IMUL r16, r/m16, imm8 | word register ← r/m16 ∗ sign-extended immediate byte.
IMUL r32, r/m32, imm8 | doubleword register ← r/m32 ∗ sign- extended immediate byte.
IMUL r64, r/m64, imm8 | Quadword register ← r/m64 ∗ sign-extended immediate byte.
IMUL r16, r/m16, imm16 | word register ← r/m16 ∗ immediate word.
IMUL r32, r/m32, imm32 | doubleword register ← r/m32 ∗ immediate doubleword.
IMUL r64, r/m64, imm32 | Quadword register ← r/m64 ∗ immediate doubleword.
违反严格别名规则会产生未定义的行为,例如,当通过网络将结构发送到char缓冲区时,然后该char指针被C-style/< code > STD::reinterpret _ cast()强制转换为结构指针。 C函数看起来可以用于以(实现?)定义的方式转换此类指针,即不违反严格的混淆现象规则。 示例: 因此,的调用方以某种方式获得了一个指针,并确定它实际上指向一个struct。 那么,通过 进行此类
我在Rust中尝试函数指针魔术,最后得到了一个代码片段,我完全无法解释它为什么要编译,甚至无法解释它为什么要运行。 我无法解释为什么调用的方法是在
我想知道实际上是如何工作的。我认为这是一种计算数组长度的简单方法,并希望在使用它之前适当地理解它。我对指针算术不是很有经验,但根据我的理解,给出了数组第一个元素的地址。将按地址转到数组的末尾。但是不应该给出这个地址的值吗。而是打印出地址。我真的很感激你帮我把指针的东西弄清楚。 下面是我正在研究的一个简单示例:
本文向大家介绍什么是指向指针的指针? 相关面试题,主要包含被问及什么是指向指针的指针? 时的应答技巧和注意事项,需要的朋友参考一下 指针指向的变量是一个指针,即具体内容为一个指针的值,是一个地址. 此时指针指向的变量长度也是4位.
6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = π 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int
一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType