1.1
#include
int main() {
return 0;
}
(gdb) disas
Dump of assembler code for function main:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp 建立堆栈
0x00000000004004da <+4>: mov $0x0,%eax 返回值0
0x00000000004004df <+9>: pop %rbp
0x00000000004004e0 <+10>: retq
End of assembler dump.
1.2
#include
int main() {
return 10;
}
Dump of assembler code for function main:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
=> 0x00000000004004da <+4>: mov $0xa,%eax
0x00000000004004df <+9>: pop %rbp
0x00000000004004e0 <+10>: retq
End of assembler dump.
2.1
#include
void fun1() {
}
int main() {
fun1();
return 10;
}
Dump of assembler code for function main:
0x00000000004004dd <+0>: push %rbp
0x00000000004004de <+1>: mov %rsp,%rbp
0x00000000004004e1 <+4>: mov $0x0,%eax
0x00000000004004e6 <+9>: callq 0x4004d6
=> 0x00000000004004eb <+14>: mov $0xa,%eax
0x00000000004004f0 <+19>: pop %rbp
0x00000000004004f1 <+20>: retq
End of assembler dump.
Dump of assembler code for function fun1:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
=> 0x00000000004004da <+4>: nop
0x00000000004004db <+5>: pop %rbp
0x00000000004004dc <+6>: retq
End of assembler dump.
2.2
#include
int fun1() {
return 16;
}
int main() {
fun1();
return 10;
}
Dump of assembler code for function fun1:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
0x00000000004004da <+4>: mov $0x10,%eax
0x00000000004004df <+9>: pop %rbp
0x00000000004004e0 <+10>: retq
End of assembler dump.
Dump of assembler code for function main:
0x00000000004004e1 <+0>: push %rbp
0x00000000004004e2 <+1>: mov %rsp,%rbp
0x00000000004004e5 <+4>: mov $0x0,%eax
0x00000000004004ea <+9>: callq 0x4004d6
=> 0x00000000004004ef <+14>: mov $0xa,%eax
0x00000000004004f4 <+19>: pop %rbp
0x00000000004004f5 <+20>: retq
End of assembler dump.
2.3
#include
int fun1(int m) {
return m;
}
int main() {
fun1(16);
return 10;
}
Dump of assembler code for function fun1:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
0x00000000004004da <+4>: mov %edi,-0x4(%rbp)
0x00000000004004dd <+7>: mov -0x4(%rbp),%eax
0x00000000004004e0 <+10>: pop %rbp
0x00000000004004e1 <+11>: retq
End of assembler dump.
Dump of assembler code for function main:
0x00000000004004e2 <+0>: push %rbp
0x00000000004004e3 <+1>: mov %rsp,%rbp
0x00000000004004e6 <+4>: mov $0x10,%edi
0x00000000004004eb <+9>: callq 0x4004d6
=> 0x00000000004004f0 <+14>: mov $0xa,%eax
0x00000000004004f5 <+19>: pop %rbp
0x00000000004004f6 <+20>: retq
End of assembler dump.
2.4
#include
int fun1(int m) {
return m;
}
int main() {
int a;
a = fun1(16);
return 10;
}
Dump of assembler code for function fun1:
0x00000000004004d6 <+0>: push %rbp
0x00000000004004d7 <+1>: mov %rsp,%rbp
0x00000000004004da <+4>: mov %edi,-0x4(%rbp)
=> 0x00000000004004dd <+7>: mov -0x4(%rbp),%eax
0x00000000004004e0 <+10>: pop %rbp
0x00000000004004e1 <+11>: retq
End of assembler dump.
Dump of assembler code for function main:
0x00000000004004e2 <+0>: push %rbp
0x00000000004004e3 <+1>: mov %rsp,%rbp
0x00000000004004e6 <+4>: sub $0x10,%rsp
0x00000000004004ea <+8>: mov $0x10,%edi
0x00000000004004ef <+13>: callq 0x4004d6
0x00000000004004f4 <+18>: mov %eax,-0x4(%rbp)
=> 0x00000000004004f7 <+21>: mov $0xa,%eax
0x00000000004004fc <+26>: leaveq
0x00000000004004fd <+27>: retq
End of assembler dump.
3.1
printf("*******%s,%s,%d*******\n",__FUNCTION__,__FILE__,__LINE__);
#include
#define NUM 100
int main(){
#ifdef DEBUG
printf("*******%s,%s,%d*******\n",__FUNCTION__,__FILE__,__LINE__);
#endif
printf("Hello!\n");
return 0;
}
root@vultr:~/clang# ls
002.c
root@vultr:~/clang# gcc -DDEBUG -o 002 002.c
root@vultr:~/clang# ls
002 002.c
root@vultr:~/clang# ./002
*******main,002.c,5*******
Hello!
root@vultr:~/clang# rm 002
root@vultr:~/clang# ls
002.c
root@vultr:~/clang# gcc -o 002 002.c
root@vultr:~/clang# ls
002 002.c
root@vultr:~/clang# ./002
Hello!
root@vultr:~/clang# ^C
root@vultr:~/clang#
3.2
ANSI C一共只有32个关键字,9种控制语句,程序书写形式自由,区分大小写。把高级语言的基本结构和语句与低级语言的实用性结合起来。 C 语言可以像汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元。
C语言的运算符包含的范围很广泛,共有34种运算符。C语言把括号、赋值、强制类型转换等都作为运算符处理。从而使C语言的运算类型极其丰富,表达式类型多样化。灵活使用各种运算符可以实现在其它高级语言中难以实现的运算。
关键字
sizeof
,非函数!所以在任何环境下都可以使用。
关键字
return
,函数返回。
char int short long unsigned signed float double void
struct union enum typedef
,定义数据类型,圈地用的。
if
、else
switch
、case
、default
do
、while
、for
continue
、break
、goto
,逻辑结构,控制干活儿的顺序:顺序执行、分支执行、循环执行。
auto
、register
、static
、const
、extern
、volatile
,类型修饰符,(修饰数据类型,用来修饰上面那些个限制内存大小的数据类型),对内存资源存放位置的限定。
部分关键字解释:
break:跳出当前循环
continue:结束当前循环,开始下一轮循环
case:开关语句分支
default:开关语句中的“其它”分支
goto:无条件跳转语句
return :子程序返回语句(可以带参数,也可不带参数)
register:声明寄存器变量
sizeof:计算数据类型或变量长度(即所占字节数)
volatile:说明变量在程序执行中可被隐含地改变
auto :声明自动变量
extern:声明变量或函数是在其它文件或本文件的其他位置定义
Relevant Link:
c语言关键字总结 - 二郎三郎 - 博客园
算术操作运算:
+ - * / %
逻辑运算(返回结果0或1,假就是零,非零就是真):
|| &&
> >= < <=
!
? :
位运算:
<<
>>
|
&
^
~
赋值运算:
=
+=
-=
&=
...
内存访问符号:
()
[]
{}
->
.
&
*
Relevant Link:
异或运算的性质及用途 - 氏名無 - CSDN博客
3.3
register关键字
//"register.c"
#include
int main(){
register int a;
a=0x10;
printf("the a is %d\n",a);
return 0;
}
//"register2.c"
#include
int main(){
int a;
a=0x10;
printf("the a is %d\n",a);
return 0;
}
root@vultr:~/clang# ls
register2.c register.c
root@vultr:~/clang# gcc -o register register.c
root@vultr:~/clang# gcc -o register2 register2.c
root@vultr:~/clang# ls
register register2 register2.c register.c
root@vultr:~/clang# ./register
the a is 16
root@vultr:~/clang# ./register2
the a is 16
root@vultr:~/clang# rm register register2
root@vultr:~/clang# ls
register2.c register.c
root@vultr:~/clang# gcc -c -o register register.c
root@vultr:~/clang# gcc -c -o register2 register2.c
root@vultr:~/clang# ls
register register2 register2.c register.c
root@vultr:~/clang# objdump -d register
register: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 53 push %rbx
5: 48 83 ec 08 sub $0x8,%rsp
9: bb 10 00 00 00 mov $0x10,%ebx
e: 89 de mov %ebx,%esi
10: bf 00 00 00 00 mov $0x0,%edi
15: b8 00 00 00 00 mov $0x0,%eax
1a: e8 00 00 00 00 callq 1f
1f: b8 00 00 00 00 mov $0x0,%eax
24: 48 83 c4 08 add $0x8,%rsp
28: 5b pop %rbx
29: 5d pop %rbp
2a: c3 retq
root@vultr:~/clang# objdump -d register2
register2: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: c7 45 fc 10 00 00 00 movl $0x10,-0x4(%rbp)
f: 8b 45 fc mov -0x4(%rbp),%eax
12: 89 c6 mov %eax,%esi
14: bf 00 00 00 00 mov $0x0,%edi
19: b8 00 00 00 00 mov $0x0,%eax
1e: e8 00 00 00 00 callq 23
23: b8 00 00 00 00 mov $0x0,%eax
28: c9 leaveq
29: c3 retq
root@vultr:~/clang#
3.4
//"shiftr.c"
#include
int main(){
int a=32;
while(a){
a=a>>1;
}
printf("**************\n");
}
root@vultr:~/clang# gcc -o shiftr shiftr.c
root@vultr:~/clang# ls
shiftr shiftr.c
root@vultr:~/clang# ./shiftr
**************
root@vultr:~/clang# gcc -c -o shiftr.o shiftr.c
root@vultr:~/clang# ls
shiftr shiftr.c shiftr.o
root@vultr:~/clang# objdump -d shiftr.o
shiftr.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: c7 45 fc 20 00 00 00 movl $0x20,-0x4(%rbp)
f: eb 03 jmp 14
11: d1 7d fc sarl -0x4(%rbp)
14: 83 7d fc 00 cmpl $0x0,-0x4(%rbp)
18: 75 f7 jne 11
1a: bf 00 00 00 00 mov $0x0,%edi
1f: e8 00 00 00 00 callq 24
24: b8 00 00 00 00 mov $0x0,%eax
29: c9 leaveq
2a: c3 retq
root@vultr:~/clang#
修改为int a=-32;
,会让程序陷入死循环。
root@vultr:~/clang# gcc -o shiftr shiftr.c
root@vultr:~/clang# ./shiftr
^C
root@vultr:~/clang# gcc -c -o shiftr.o shiftr.c
root@vultr:~/clang# ls
shiftr shiftr.c shiftr.o
root@vultr:~/clang# objdump -d shiftr.o
shiftr.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 :
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: c7 45 fc e0 ff ff ff movl $0xffffffe0,-0x4(%rbp)
f: eb 03 jmp 14
11: d1 7d fc sarl -0x4(%rbp)
14: 83 7d fc 00 cmpl $0x0,-0x4(%rbp)
18: 75 f7 jne 11
1a: bf 00 00 00 00 mov $0x0,%edi
1f: e8 00 00 00 00 callq 24
24: b8 00 00 00 00 mov $0x0,%eax
29: c9 leaveq
2a: c3 retq
root@vultr:~/clang#