从高级语言到汇编代码 《Linux内核分析》笔记
标签(空格分隔): Linux C语言 汇编 编译 源码剖析
《Linux内核分析》是网易云课堂的一门MOOC,本文是该课的笔记&作业
前言
在课堂内容中,从底层讲起,介绍了体系结构的宏观概念,然后X86指令、寄存器、汇编代码。在实验中,反过来从较为高级的C语言,产生的汇编代码介绍计算机的具体行为。
实验过程
在Linux下编译生成一个简单C程序的汇编。
C源程序:
int g(int x)
{
return x + 4;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(32) + 2;
}
编译命令:
gcc –S –o main.s main.c -m32
生成目标文件:
.file "main.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
movl 8(%ebp), %eax
addl $4, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $4, %esp
movl $32, (%esp)
call f
addl $2, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
.section .note.GNU-stack,"",@progbits
.开头的是链接的辅助信息,去除后就是汇编代码:
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $4, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $32, (%esp)
call f
addl $2, %eax
leave
ret
过程分析
计算机工作的原理
实验的过程帮助我们由抽象到具象,从接近人类语言的高级语言,经过编译、汇编,生成了汇编语言,汇编语言将助记符改换成2进制也就变成了机器可读的机器语言,而汇编已经很明显具备了我们组成原理中介绍的指令的形式,三元或者四元式,具备一个操作符和数个地址(操作数)。
回到一开始介绍计算机的冯诺依曼结构,该体系下,指令和数据都被表达成数据,在同一个存储区域内,具有同一种地址形式,当执行时,根据编制好的程序取用,即为存储程序计算机。
Jin Youzhi 原创作品转载请注明出处
《Linux内核分析》MOOC课程
http://mooc.study.163.com/course/USTC-1000029000