Featured image of post Princlples of Compiler Experiment2

Princlples of Compiler Experiment2

编译器设计原理实验报告2


1.1 如果在命令行下执行 gcc -DNEG -E sample.c -o sample.i 生成的 sample.i 与之前的有何区别?

  • -D定义了NEG变量,因此在预处理时,M将被替换为-4,而不加-DNEGM将赋值为4。

1.2 请对比 sample-32.s 和 sample.s ,找出它们的区别,并上网检索给出产生这些区别的原因。如:

pushq 和 pushl
  • pushlpushq的区别在于操作的位数不同,具体来说pushl压入一个双字的长度即32位,而pushq压入一个四字的长度即64位。在32位系统中,ebp为32位,而在64位系统中,rbp为64位。

补充:

  • pushb:压入一个 byte(8 位)
  • pushw:压入一个 word(16 位)
  • pushl:压入一个 long(32 位)
  • pushq:压入一个 quadword(64 位)
rsp 和 esp
  • 他们都是栈顶指针
  • esp为32位栈顶指针
  • rsp为64位栈顶指针

1.3 你可以用 clang 替换 gcc ,重复上面的各步,比较使用 clang 和 gcc 分别输出的结果有何异同。【本题可选】

  • GCC的输出如下:

    点击查看GCC生成的sample.s
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
        .file	"sample.c"
        .text
        .globl	main
        .type	main, @function
    main:
    .LFB0:
        .cfi_startproc
        pushq	%rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq	%rsp, %rbp
        .cfi_def_cfa_register 6
        movl	$4, -4(%rbp)
        cmpl	$0, -4(%rbp)
        je	.L2
        addl	$4, -4(%rbp)
        jmp	.L3
    .L2:
        sall	$2, -4(%rbp)
    .L3:
        movl	$0, %eax
        popq	%rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
    .LFE0:
        .size	main, .-main
        .ident	"GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
        .section	.note.GNU-stack,"",@progbits
    
  • clang的输出如下:

    点击查看clang生成的sample-clang.s
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
        .text
        .file	"sample.c"
        .globl	main                    # -- Begin function main
        .p2align	4, 0x90
        .type	main,@function
    main:                                   # @main
        .cfi_startproc
    # %bb.0:
        pushq	%rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq	%rsp, %rbp
        .cfi_def_cfa_register %rbp
        movl	$0, -4(%rbp)
        movl	$4, -8(%rbp)
        cmpl	$0, -8(%rbp)
        je	.LBB0_2
    # %bb.1:
        movl	-8(%rbp), %eax
        addl	$4, %eax
        movl	%eax, -8(%rbp)
        jmp	.LBB0_3
    .LBB0_2:
        movl	-8(%rbp), %eax
        shll	$2, %eax
        movl	%eax, -8(%rbp)
    .LBB0_3:
        xorl	%eax, %eax
        popq	%rbp
        retq
    .Lfunc_end0:
        .size	main, .Lfunc_end0-main
        .cfi_endproc
                                            # -- End function
    
        .ident	"clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)"
        .section	".note.GNU-stack","",@progbits
    
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus