long exchange(long *xp, long y)
{
long x = *xp;
*xp = y;
return x;
}
执行指令
gcc -Og -S exchange.c
cat exchange.s
输出
.file "exchange.c"
.text
.globl exchange
.type exchange, @function
exchange:
.LFB0:
.cfi_startproc
movq (%rdi), %rax
movq %rsi, (%rdi)
ret
.cfi_endproc
.LFE0:
.size exchange, .-exchange
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-39)"
.section .note.GNU-stack,"",@progbits
这个例子展示了MOV
指令如何从内存读取值到寄存器,如何将值从寄存器写入到内存。
分析
- 函数
exchange
仅使用3条指令:两条数据移动指令movq
和一条返回到调用函数exchange
的位置的指令ret
。 - 传递给函数的实参在寄存器中。
- 函数通过将值保存在寄存器
%rax
或者该寄存器中的低位部分之一来实现返回值。
- 当函数
exchange
开始执行时,函数参数xp
和y
分别存储在%rdi
和%rsi
中。 - 然后,指令
movq (%rdi), %rax
从内存中读取x
,将值保存在寄存器%rax
中,直接实现了操作x = *xp
。 - 接着,指令
movq %rsi, (%rdi)
将y写入寄存器%rdi
中的xp
指向的内存位置,直接实现操作*xp = y
。 - 最后,使用寄存器
%rax
从函数exchange
中返回值,所以返回值是x
。
注意:
- 在C语言中的指针只是地址而已,这点可从查看C源代码对应的汇编码可知。
- 解析一个指针包括拷贝该指针到寄存器,然后在内存引用中使用寄存器。
- 比如局部变量
x
是存储在寄存器中,而不是内存位置。寄存器的访问速度要比内存块。
网友评论