下面介绍简单的C代码会生成怎样的汇编。
当定义一个变量时,其类型就说明了他在内存中所占的字节数,编译器会生成一个符号表,用来映射变量名及变量在内存中的存储位置。
在我们的例子中,默认int型总占四个字节,并且不考虑变量在内存中实际位置。
例1
{
int i;
i = 6;
i++;
}
翻译成汇编代码可如下:
M[R1] = 6 ; assign i the value 6
R2 = M[R1] ; load i's value into a register
R2 = R2 + 1 ; do the addition
M[R1] = R2 ; store new value into i
由此可以看出一条较高层次的指令(C语言)指令往往需要几条较低层次的指令(汇编)来解释。所以有时候编译器生成的汇编往往没有手动直接写的汇编效率高,当然聪明的编译器可能会把如上C语言代码直接翻译成 M[R1] = 7;
例2
{
char ch;
ch = 'A';
}
char 类型的变量只占有一个字节,所以翻译成汇编代码如下:
M[R1] =.1 65 ; 65 is ASCII value of 'A'
在C语言中char、 short、 int以及long都是属于同一系列的变量,他们在内存中采样的是同样方式的二进制表示方式。 当把小的变量类型转换成较大的变量类型时,是没有什么问题的,
例3
{
char ch;
int i;
ch = 'A';
i = ch;
}
翻译成汇编如下:
M[R1 + 4] =.1 65 ; assign ch ASCII value 'A'
R2 =.1 M[R1 + 4] ; load ch into R2 (upper bytes of R2 are zeroed)
M[R1] = R2 ; assign value in R2 to i
但是作相反的转换有时就不这么简单了,如下代码他只把i变量的代字节数据复制到ch中去,而其它的高字节都会丢弃了,
例4
{
char ch;
int i;
i = 1025;
ch = i;
}
翻译成汇编如下:
M[R1] = 1025 ; assign i the value 1025
R2 = M[R1] ; load value of i into R2
M[R1 + 4] =.1 R2 ; copy lower byte of R2 to ch
浮点数与整型数据之间需要转换,
例5
{
int i;
float f;
f = 3.14159
i = f;
}
翻译成汇编代码:
M[R1] = 3.14159 ; assign f the value 3.14159
R2 = M[R1] ; load value of f into R2
R3 = FtoI R2 ; convert value in R2 from float to int, store in R3
M[R1 + 4] = R3 ; copy value in R3 to i
再次强调此汇编代码只作示例用,还是屏蔽掉很多细节的。
再复杂点的例子如
例6
{
int total, count;
float average;
average = ((float) total)/((float) count);
}
假设average存存地址存于R1中,则翻译成的汇编如下:
R2 = M[R1 + 8] ; load value of total
R3 = ItoF R2 ; convert int to float
R4 = M[R1 + 4] ; load value of count
R5 = ItoF R4 ; convert int to float
R6 = R3/R5 ; divide (floating point version)
M[R1] = R6 ; store in average
那对于结构体、指针等数据类型将会生成怎样的汇编代码呢,下一节将一一道来。