linux内核分析-简单C语言及汇编过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scylhy/article/details/86351937

简单C语言及汇编过程

最近复习准备PaaS考试,看Docker部分的linux内核,突感兴许,之前看的unix高级  
环境编程,也仅剩丁点记忆,故翻到网易云课堂上,老早想看,但始终未看的Linux  
内核分析,打算放假回家把这部分结束了,现在就开个头吧。
看前觉得挺多,且无聊,学完一段后,还是挺有趣的~~
  • code
int g(int x)
{
  return x + 3;
}
int f(int x)
{
  return g(x);
}
int main(void)
{
  return f(8) + 1;
}
  • C语言生成可执行文件的过程

    • 生成汇编代码
    root@lhys:~/linuxcore# gcc main.c  -S -o main.s
    root@lhys:~/linuxcore# cat main.s
    	.file	"main.c"
    	.text
    	.globl	g
    	.type	g, @function
    g:
    .LFB0:
    	.cfi_startproc
    	pushq	%rbp
    	.cfi_def_cfa_offset 16
    	.cfi_offset 6, -16
    	movq	%rsp, %rbp
    	.cfi_def_cfa_register 6
    	movl	%edi, -4(%rbp)
    	movl	-4(%rbp), %eax
    	addl	$3, %eax
    	popq	%rbp
    	.cfi_def_cfa 7, 8
    	ret
    	.cfi_endproc
    .LFE0:
    	.size	g, .-g
    	.globl	f
    	.type	f, @function
    f:
    .LFB1:
    	.cfi_startproc
    	pushq	%rbp
    	.cfi_def_cfa_offset 16
    	.cfi_offset 6, -16
    	movq	%rsp, %rbp
    	.cfi_def_cfa_register 6
    	subq	$8, %rsp
    	movl	%edi, -4(%rbp)
    	movl	-4(%rbp), %eax
    	movl	%eax, %edi
    	call	g
    	leave
    	.cfi_def_cfa 7, 8
    	ret
    	.cfi_endproc
    .LFE1:
    	.size	f, .-f
    	.globl	main
    	.type	main, @function
    main:
    .LFB2:
    	.cfi_startproc
    	pushq	%rbp
    	.cfi_def_cfa_offset 16
    	.cfi_offset 6, -16
    	movq	%rsp, %rbp
    	.cfi_def_cfa_register 6
    	movl	$8, %edi
    	call	f
    	addl	$1, %eax
    	popq	%rbp
    	.cfi_def_cfa 7, 8
    	ret
    	.cfi_endproc
    .LFE2:
    	.size	main, .-main
    	.ident	"GCC: (Ubuntu 7.3.0-16ubuntu3) 7.3.0"
    	.section	.note.GNU-stack,"",@progbits
    root@lhys:~/linuxcore# 
    
    • 汇编
    root@lhys:~/linuxcore# gcc -c main.s -o main.o
    root@lhys:~/linuxcore# ls
    main.c  main.o  main.s
    root@lhys:~/linuxcore# cat main.o
    ELF>@@
    
          UH??}??E???]?UH??H??}??E??????UH????]?GCC: (Ubuntu 7.3.0-16ubuntu3) 7.3.0zRx
    J                                                                                A?C
    RA?C
    NA?C
    ??
    
    &main.cgfmain????????0	???????? @`&.symtab.strtab.shstrtab.rela.text.data.bss.comment.note.GNU-stack.rela.eh_frame @980       &yy10y%:?O?J@hH	
     ?Y
    root@lhys:~/linuxcore# 
    
    • 链接
    root@lhys:~/linuxcore# gcc main.o 
    root@lhys:~/linuxcore# ls
    a.out  main.c  main.o  main.s
    root@lhys:~/linuxcore# ./a.out 
    root@lhys:~/linuxcore# 
    
  • c代码执行和汇编执行的过程分析

    • 删除汇编代码中的辅助代码(.开头的信息)
    g:
        pushq   %rbp
        movq    %rsp, %rbp      //前两句生成空栈,即g的函数栈
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax  //eax寄存器默认存储返回值
        addl    $3, %eax
        popq    %rbp	        //退回到g开始前的栈位置,即存eip的位置
        ret				        //即popl $eip,程序计数器指向调用g的下一条指令位置
    f:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $8, %rsp
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax
        movl    %eax, %edi
        call    g	            //即pushl %eip,movl g $eip,保存下一条指令位置,并跳转到g
        leave	                //即movl $ebp %esp,popl %ebp,恢复到上一个栈区,并指向调用前存储的eip
        ret
    main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $8, %edi
        call    f
        addl    $1, %eax
        popq    %rbp
        ret
    
    • 执行过程演示图(来自网络,生成的汇编略有不同)
      在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/scylhy/article/details/86351937