1.1 如果在命令行下执行 gcc -DNEG -E sample.c -o sample.i 生成的 sample.i 与之前的有何区别?
-D
定义了NEG
变量,因此在预处理时,M
将被替换为-4,而不加-DNEG
,M
将赋值为4。
1.2 请对比 sample-32.s 和 sample.s ,找出它们的区别,并上网检索给出产生这些区别的原因。如:
pushq 和 pushl
pushl
与pushq
的区别在于操作的位数不同,具体来说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, @functionmain:.LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movl $4, -4(%rbp)cmpl $0, -4(%rbp)je .L2addl $4, -4(%rbp)jmp .L3.L2:sall $2, -4(%rbp).L3:movl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.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,@functionmain: # @main.cfi_startproc# %bb.0:pushq %rbp.cfi_def_cfa_offset 16.cfi_offset %rbp, -16movq %rsp, %rbp.cfi_def_cfa_register %rbpmovl $0, -4(%rbp)movl $4, -8(%rbp)cmpl $0, -8(%rbp)je .LBB0_2# %bb.1:movl -8(%rbp), %eaxaddl $4, %eaxmovl %eax, -8(%rbp)jmp .LBB0_3.LBB0_2:movl -8(%rbp), %eaxshll $2, %eaxmovl %eax, -8(%rbp).LBB0_3:xorl %eax, %eaxpopq %rbpretq.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