转载必须注明出处,违者必究。http://www.cnblogs.com/dennisOne
本文试图从汇编语言的角度回答下面几个问题:
- 在C语言中直接使用寄存器;
- C语言如何直接操作内存;
- C语言的内存的管理;
- C语言的参数传递和返回值;
- C语言中的可变参数传递;
-
C语言直接使用寄存器
在TC中可以直接使用寄存器.
1 main()
2 {
3 _AX = 1;
4 _BX = 1;
5 _CX = 2;
6 _AX = _BX + _CX;
7 _AH = _BL + _CL;
8 }debug之后的代码:
-
C语言通过指针来直接操作内存
1 main()
2 {
3 *(char *)0x2000 = 'a'; /* 0x2000是偏移地址 */
4 *(int *)0x2000 = 0xf;
5 *(char far *)0x20001000 = 'a'; /* 2000:1000 */
6
7 _BX = 0x2000;
8 *(char *)_BX = 'b';
9
10 *(char far *)(0x20001000 + _BX) = *(char *)_AX;
11
12 }debug之后的代码:
-
C语言的内存的管理
例1:示例代码
1 int a1, a2; /* 全局变量 */
2
3 void f(void);
4
5 main(void)
6 {
7 int b1, b2; /* 局部变量 */
8 static int s; /* static变量 */
9 a1 = 0xa1; a2 = 0xa2;
10 b1 = 0xb1; b2 = 0xb2;
11 s = 0x1;
12 }
13
14 void f(void)
15 {
16 int c1, c2;
17 a1 = 0xfa1; a2 = 0xfa2;
18 c1 = 0xc1; c2 = 0xc2;
19 }debug之后的代码:
分析代码:"
总结:
- 局部变量放在栈区,按照声明的顺序由低到高存放。
- 静态变量和全局变量都是放在全局区,按照声明的顺序由低到高存放。
- [补充结论], 形参也是放在栈区,也是按照声明的顺序由低到高依次存放[后面可以证明]。
-
参数传递和结果返回
(1). 参数传递
1 void f(char a, int b);
2
3 main()
4 {
5 f('a', 2);
6 }
7
8 void f(char a, int b)
9 {
10 a = 'c';
11 b = 300;
12 }分析代码:
总结:
- 可以看出,tc编译生成的可执行程序,形参内存的分配和释放都是由主调函数完成,上图中黑色箭头所示。
- 主调函数调用被调函数,call的过程意味着ip入栈;然后将bp入栈(bp始终记录了这被调函数的栈顶,可以通过bp向下访问形参;向*问局部变量);sp始终指向栈顶。
- 栈中依次排放: …<…<-(IP) <-形参<-局部变量 <-(bp)。
(2). 结果返回
1 int f(void);
2
3 main(void)
4 {
5 int c;
6 c = f();
7 }
8
9 int f(void)
10 {
11 int a, b, sum;
12 sum = a + b;
13 return sum;
14 }debug之后
分析代码:
可以看出返回值是放入一个寄存器AX进行暂存的。
-
可变参数
上述分析我们知道,形参可以通过BP来访问。这就为C语言使用可变参数机制va_list可以看成是对BP的抽象。