https://godbolt.org/g/WAq2MM汇编翻译网站
A note on register use
Addressing modes


(float )ptr后

ptr[7]后

ptr = (ptr + 1)后
Signed/unsigned arithmetic


int和unsgined int汇编是一样的,
Lea, multiplication by a constant


可以直接用lea指令进行算术运算,有时候更方便也更节约资源提升效率,乘法是消耗计算资源最多的几个命令之一,用lea代替是个不错的选择。




lea作算术运算更多的例子


因为lea的缩放系数只能取1、2、4、8,所以当乘23时,就没有用lea指令了,而是常规的乘法。


同样,16超出了lea缩放系数的范围,所以用了移位,移位的代价仍然比乘法小。


小的不是2的次幂的数字,编译器会想办法用最高校的方式替换乘法.

17用lea凑不出来了,用移位和加法来凑。16 + 1 = 17.

25是个较小的平方数,可以用lea凑出来,x + 4x = 5x,5x + 4*5x = 25x
gcc非常不想用乘法


14是编译器不得不用乘法的最小的数字
Constant folding 常量折叠
An expression that involves only constants can be evaluated at compile-time and have its result substituted into the generated assembly. This compiler feature
is called constant folding.
大概就是说,如果一个表达式全都由常量组成,那么它会被编译时算出来,代入生成的汇编中。编译器的这种特性叫做constant folding。
#include <limits.h>int abs_val(int x){int sn = x >> (sizeof(int)*CHAR_BIT -1);return (x ^ sn) - sn;}int has_zero_byte(unsigned long val){unsigned long ones = ~0UL/UCHAR_MAX;unsigned long highs = ones << (CHAR_BIT - 1);return (((val - ones) & highs) & ~val) != 0;}int constant_fold(int x){return 10 + ((22*45 + 48)*13 - 100)*x - 1;}


如图,汇编代码中,直接代入了这些表达式的值,注意这些值是十进制。
2) Tools
Deadlisting with objdump
GDB commands for live assembly debugging
disassemble

GDB 的 disassemble命令不加参数可以打印当前正在执行的函数的汇编代码。
b address和b myfn+8


打印出汇编代码及指令地址,就可以看着代码在地址处打断点,或者用函数 + 偏移的方式打断点。
stepi和nexti(si和ni)
info reg打印所有寄存器、打印单个寄存器内容、设置寄存器值
tui (text user interface)
Reading and tracing assembly in GDB



<+67>处,编译器直接算出了字符数组常量的长度,编译成汇编是就直接将长度作为常量代入了汇编代码,而不是在汇编代码执行时进入strlen进行计算,相当于constant folding常量折叠。

看不出来count的值从何而来,只有<+91>处有个0x6,猜测编译器在编译时就已经算出来count的值。


代码执行到for循环内,打印局部变量和参数,squared变量是
继续执行到退出for循环,打印局部变量,
发现 i 消失,而且total变为
二者不能同时为
整个过程都没有number,count变量,所以结合上面的汇编代码可以推断出,编译器编译后,把这两个当作常量对待,直接把他们的值代入了程序的执行
,而不是程序执行时再计算他们的值。
3) Writing assembly
# File: asm.s
# -----------
# These fuctions are implemented in assembly and linked with C code
.section .text
.type sample, @function
.globl sample
sample:
cmpl %edi, %esi
je .L1
movl %esi, %eax
addl %edi, %eax
ret
.L1:
movl $22, %eax
ret
.type mine, @function
.globl mine
mine:
# this function currently empty, yours to fill in!
cmpl %edi, %esi
jg .second_bigger
movl %edi, %eax
subl %esi, %eax
ret
.second_bigger:
movl %esi, %eax
subl %edi, %eax
ret
solution:
# File: asm.s
# -----------
# These fuctions are implemented in assembly and linked with C code
.section .text
.type sample, @function
.globl sample
sample:
cmpl %edi, %esi
je .L1
movl %esi, %eax
addl %edi, %eax
ret
.L1:
movl $22, %eax
ret
.type mine, @function
.globl mine
mine:
# this function currently empty, yours to fill in!
#mov $0, %eax
#make sure upper bits are 0s or 1s depending on sign
salq $32, %rdi
salq $32, %rsi
sarq $32, %rdi
sarq $32, %rsi
subq %rsi, %rdi
movq %rdi, %rax
cmpq $0, %rax
jns .pos
negl %eax
.pos:
ret






