··

编译器设计原理实验报告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
    .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
    .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