实验链接
实验报告
第1关:理解程序的不同表示形式
##问题1-1:
如果在命令行下执行
gcc -DNEG -E sample.c -o sample.i
生成的sample.i 与之前的有何区别?
根据定义NEG,而选择了M定义为-4
##问题1-2
请对比sample-32.s和sample.s,找出它们的区别,并上网检索给出产生这些区别的原因。如:
- pushq和pushl
- rsp和esp
sample-32.s和sample.s的区别
diff sample-32.s sample.s
1,4c1,6
< .file "sample.c"
< .text
< .globl main
< .type main, @function
---
> .arch armv8-a
> .file "sample.c"
> .text
> .align 2
> .global main
> .type main, %function
6,18c8,17
< .LFB0:
< .cfi_startproc
< pushl %ebp
< .cfi_def_cfa_offset 8
< .cfi_offset 5, -8
< movl %esp, %ebp
< .cfi_def_cfa_register 5
< subl $16, %esp
< movl $4, -4(%ebp)
< cmpl $0, -4(%ebp)
< je .L2
< addl $4, -4(%ebp)
< jmp .L3
---
> sub sp, sp, #16
> mov w0, -4
> str w0, [sp, 12]
> ldr w0, [sp, 12]
> cmp w0, 0
> beq .L2
> ldr w0, [sp, 12]
> add w0, w0, 4
> str w0, [sp, 12]
> b .L3
20c19,21
< sall $2, -4(%ebp)
---
> ldr w0, [sp, 12]
> lsl w0, w0, 2
> str w0, [sp, 12]
22,31c23,28
< movl $0, %eax
< leave
< .cfi_restore 5
< .cfi_def_cfa 4, 4
< ret
< .cfi_endproc
< .LFE0:
< .size main, .-main
< .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
< .section .note.GNU-stack,"",@progbits
---
> mov w0, 0
> add sp, sp, 16
> ret
> .size main, .-main
> .ident "GCC: (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
> .section .note.GNU-stack,"",@progbits
问题1-3 你可以用clang替换gcc,重复上面的各步,比较使用clang和gcc分别输出的结果有何异同。
gcc sample.c -o sample -v
clang sample.c -o sample -v
diff gcc.txt clang.txt
1,5c1,2
< Using built-in specs.
< COLLECT_GCC=gcc
< COLLECT_LTO_WRAPPER=/usr/lib/gcc/aarch64-linux-gnu/5/lto-wrapper
< Target: aarch64-linux-gnu
< Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-arm64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-arm64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-arm64 --with-arch-directory=aarch64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu
---
> clang version 10.0.1
> Target: aarch64-unknown-linux-gnu
7,14c4,14
< gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.12)
< COLLECT_GCC_OPTIONS='-o' 'sample' '-v' '-mlittle-endian' '-mabi=lp64'
< /usr/lib/gcc/aarch64-linux-gnu/5/cc1 -quiet -v -imultiarch aarch64-linux-gnu sample.c -quiet -dumpbase sample.c -mlittle-endian -mabi=lp64 -auxbase sample -version -fstack-protector-strong -Wformat -Wformat-security -o /tmp/cc1Kcmw6.s
< GNU C11 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.12) version 5.4.0 20160609 (aarch64-linux-gnu)
< compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3
< GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
< ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
< ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/5/../../../../aarch64-linux-gnu/include"
---
> InstalledDir: /opt/llvm10/llvm-install/bin
> Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/5
> Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/5.4.0
> Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/6
> Found candidate GCC installation: /usr/lib/gcc/aarch64-linux-gnu/6.0.0
> Selected GCC installation: /usr/lib/gcc/aarch64-linux-gnu/5.4.0
> Candidate multilib: .;@m64
> Selected multilib: .;@m64
> "/opt/llvm10/llvm-install/bin/clang-10" -cc1 -triple aarch64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sample.c -mrelocation-model static -mthread-model posix -mframe-pointer=non-leaf -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -target-cpu generic -target-feature +neon -target-abi aapcs -fallow-half-arguments-and-returns -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -v -resource-dir /opt/llvm10/llvm-install/lib/clang/10.0.1 -internal-isystem /usr/local/include -internal-isystem /opt/llvm10/llvm-install/lib/clang/10.0.1/include -internal-externc-isystem /usr/include/aarch64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /data/workspace/myshixun -ferror-limit 19 -fmessage-length 0 -fno-signed-char -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o /tmp/sample-ee930b.o -x c sample.c
> clang -cc1 version 10.0.1 based upon LLVM 10.0.1 default target aarch64-unknown-linux-gnu
> ignoring nonexistent directory "/include"
17d16
< /usr/lib/gcc/aarch64-linux-gnu/5/include
19c18
< /usr/lib/gcc/aarch64-linux-gnu/5/include-fixed
---
> /opt/llvm10/llvm-install/lib/clang/10.0.1/include
23,33c22
< GNU C11 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.12) version 5.4.0 20160609 (aarch64-linux-gnu)
< compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3
< GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
< Compiler executable checksum: 0aba823f581e395c09d29a3a6f3b731f
< COLLECT_GCC_OPTIONS='-o' 'sample' '-v' '-mlittle-endian' '-mabi=lp64'
< as -v -EL -mabi=lp64 -o /tmp/cc281Jv1.o /tmp/cc1Kcmw6.s
< GNU assembler version 2.26.1 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.26.1
< COMPILER_PATH=/usr/lib/gcc/aarch64-linux-gnu/5/:/usr/lib/gcc/aarch64-linux-gnu/5/:/usr/lib/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/5/:/usr/lib/gcc/aarch64-linux-gnu/
< LIBRARY_PATH=/usr/lib/gcc/aarch64-linux-gnu/5/:/usr/lib/gcc/aarch64-linux-gnu/5/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/5/../../../../lib/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/opt/llvm10/antlr4-cpp/dist/:/opt/llvm10/antlr4-cpp/dist/:./:/usr/lib/gcc/aarch64-linux-gnu/5/../../../:/lib/:/usr/lib/
< COLLECT_GCC_OPTIONS='-o' 'sample' '-v' '-mlittle-endian' '-mabi=lp64'
< /usr/lib/gcc/aarch64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/aarch64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/aarch64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccjhDePW.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/ --build-id --eh-frame-hdr --hash-style=gnu --as-needed -dynamic-linker /lib/ld-linux-aarch64.so.1 -X -EL -maarch64linux --fix-cortex-a53-843419 -z relro -o sample /usr/lib/gcc/aarch64-linux-gnu/5/../../../aarch64-linux-gnu/crt1.o /usr/lib/gcc/aarch64-linux-gnu/5/../../../aarch64-linux-gnu/crti.o /usr/lib/gcc/aarch64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/aarch64-linux-gnu/5 -L/usr/lib/gcc/aarch64-linux-gnu/5/../../../aarch64-linux-gnu -L/usr/lib/gcc/aarch64-linux-gnu/5/../../../../lib -L/lib/aarch64-linux-gnu -L/lib/../lib -L/usr/lib/aarch64-linux-gnu -L/usr/lib/../lib -L/opt/llvm10/antlr4-cpp/dist -L/opt/llvm10/antlr4-cpp/dist -L. -L/usr/lib/gcc/aarch64-linux-gnu/5/../../.. /tmp/cc281Jv1.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/aarch64-linux-gnu/5/crtend.o /usr/lib/gcc/aarch64-linux-gnu/5/../../../aarch64-linux-gnu/crtn.o
---
> "/usr/bin/ld" -EL -z relro --hash-style=gnu --eh-frame-hdr -m aarch64linux -dynamic-linker /lib/ld-linux-aarch64.so.1 -o sample /usr/lib/gcc/aarch64-linux-gnu/5.4.0/../../../aarch64-linux-gnu/crt1.o /usr/lib/gcc/aarch64-linux-gnu/5.4.0/../../../aarch64-linux-gnu/crti.o /usr/lib/gcc/aarch64-linux-gnu/5.4.0/crtbegin.o -L/usr/lib/gcc/aarch64-linux-gnu/5.4.0 -L/usr/lib/gcc/aarch64-linux-gnu/5.4.0/../../../aarch64-linux-gnu -L/lib/aarch64-linux-gnu -L/usr/lib/aarch64-linux-gnu -L/usr/lib/gcc/aarch64-linux-gnu/5.4.0/../../.. -L/opt/llvm10/llvm-install/bin/../lib -L/lib -L/usr/lib -L/opt/llvm10/antlr4-cpp/dist -L/opt/llvm10/antlr4-cpp/dist -L. /tmp/sample-ee930b.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/aarch64-linux-gnu/5.4.0/crtend.o /usr/lib/gcc/aarch64-linux-gnu/5.4.0/../../../aarch64-linux-gnu/crtn.o
第2关:理解使用库的C程序的编译和链接
问题2-1:
-nostdinc选项的用处是什么?
请列出 EduCoder 平台上 gcc C程序默认的头文件查找路径
如何在使用了-nostdinc选项的同时使得上述命令编译通过? 请进一步说明通过的原因(不能修改源文件)。
命令选项 -nostdinc 不搜索默认路径头文件
-nostdinc: 不要在标准系统目录中寻找文件,只是搜索‘-I’选项指定的目录
root@evassh-17600448:/data/workspace/myshixun/lab2# gcc -E sample-io.c -o sample-io.i
root@evassh-17600448:/data/workspace/myshixun/lab2# gcc sample-io.i -o sample-io
root@evassh-17600448:/data/workspace/myshixun/lab2# ./sample-io
Hello, world!
a=8
第3关:C 程序的编写和编译以及各种程序表示的对比
在文件HW/H3/c/sort.c中编写一个排序程序
#include<stdio.h>
#define N 1001
void selectSort(int a[], int n);
int main(){
int n;
scanf("%d", &n);
int a[N];
for(int i=0;i<n;i++){
scanf("%d", &a[i]);
}
selectSort(a, n);
for(int i=0;i<n;i++){
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
// 排序函数
void selectSort(int a[], int n)
{
for(int i=0;i<n;i++){
int k=i;
for(int j=i+1;j<n;j++){
if(a[j]<a[k]){
k=j;
}
}
if(k!=i){
int t=a[k];
a[k]=a[i];
a[i]=t;
}
}
}
在文件HW/H3/c/Makefile中编写编译规则
exe=sort
$(exe):$(wildcard *.c)
gcc -o $@ $^
.PHONY:clean
clean:
rm -f $(exe)
echo "clean object files"