从汇编角度理解C语言(一)

十一闲暇在学习Standford大学公开课《编程范示》的视频以及相关一些讲义,体会到世界一流大学课程的魅力。讲师从编程语言入手,讲到计算机体系结构、讲到编译原理、讲到操作系统、讲到函数式编程,在课堂上各种示例信手写来、行云流水,也让听者体会到入木三分、酣畅淋漓之感觉。

以下是我对有关体系统结构相关部分的学习笔记与总结,主要是讲C语言如何翻译成汇编(后面为了表达方便,我以第一人称描述) :

为了更方便及清晰地介绍C语言翻译成汇编代码是什么样子,我们以精简指令集(RISC)处理器为参考,自行设计出一套虚构的处理器汇编代码指令。

此处理器由32个寄存器,每个寄存器可存储4个字节长度的字,即32位。我们将支持以下3种类型的指令:

“Load/Store”指令用于在寄存器和内存之间移动数据;
“ALU”指令用于对寄存器中数据的操作处理;
“Branch/Jump”用于改变下一指令执行的位置,即用于指令的跳转。

下面一一介绍。

Load
此类型指令用于把数据装载到寄存器中,源可以是常量,另外一个寄存器,或者是内存地址。内存地址表达方式为Mem[address](address可以是一个常数,一个寄存器值或者寄存器加一个常数的偏移值)。
正常一般的情况下,一次存取1个字的数据(4个字节),但如果要存取的为半字或一字节时可用表达为"=.2"(1bytes),"=.1"(1byte)。

在下面举例说明中为了更精确的理解,指令上面保留了英文注释,加精部分为实际汇编指令。

举例:
Load the constant 23 into register 4 
R4 = 23 
 
Copy the contents of register 2 into register 3 
R3 = R2 
 
Load char (one byte) starting at memory address 244 into register 6 
R6 =.1 Mem[244] 
 
Load R5 with the word whose memory address is in R1 
R5 = Mem[R1] 
 
Load the word that begins 8 bytes after the address in R1. 
This is known as "constant offset" mode and is about the fanciest 
addressing mode a RISC processor will support. 
R4 = Mem[R1+8] 


Store
指令与Load指令相反,用于把数据存储到内存中去(在RISC体系结构中没有直接把数据从内存中的一个地址转移到另一个地址的方法,所以你只有先把数据装载到寄存器中,然后再存储到内存中)。

举例:
Store the constant number 37 into the word beginning at 400 
Mem[400] = 37 
 
Store the value in R6 into the word whose address is in R1 
Mem[R1] = R6 
 
Store lower half-word from R2 into 2 bytes starting at address 1024 
Mem[1024] =.2 R2 
 
Store R7 into the word whose address is 12 more than the address in R1 
Mem[R1+12] = R7 

Store R7 into the word whose address is 12 more than the address in R1 
Mem[R1+12] = R7 

ALU
ALU(Arithmetic Logical Unit)算术逻辑运算单元,他的操作只能针对寄存器和常数(有的处理器只支持寄存器操作)。

举例:
Add 6 to R3 and store the result in R1 
R1 = 6 + R3 
 
Subtract R3 from R2 and store the result in R1 
R1 = R2 - R3 

另外对于处理器来讲,处理整数和处理浮点数是采用不同方式的,并且对于除法运算,一般都需要更多的指令周期完成。 

Branch
默认情况下,CPU会从内存的低地址至高地址依次获取存并执行指令,而如果要想实现指令的跳转,就要用到Branch指令了,它通过改变PC寄存器的值来改变指令下一跳的地址。

以下是跳转指令的举例:
Begin executing at address 344 if R1 equals 0 
BEQ R1, 0, 344  "branch if equal" 
 
Begin executing at addr 8 past current instruction if R2 less than R3 
BLT R2, R3, PC+8  "branch if less than" 

以下列举出了所有跳转指令:
BLT  < (第一个数小于第二个数时跳转)
BLE  <=
BGT  >
BGE  >=  
BEQ  == 
BNE  !=

另外还有一个绝对跳转指令Jmp,举例说明如下:
Begin executing at address 2000 unconditionally- like a goto 
Jmp 2000 
 
Begin executing at address 12 before current instruction 
Jmp PC-12 

此外为了我们更方便的目的,再补充两条数据转换指令(整型与浮点型之间的转换),

Take bits in R3 that represent integer, convert to float, store in R2 
R2 = ItoF R3 
 
Take bits in R4, convert from float to int, and store back in same Note 
that converting in this direction loses information, the fractional 
component is truncated and lost 
R4 = FtoI R4 

至此,介绍过了所有要用到的汇编指令,下几章就将逐步介绍各种C语句都会翻译成怎样的汇编代码。


你可能感兴趣的:(C语言、汇编、体系结构)