实验内容
熟悉 Linux 下 x86 汇编语言编程环境
验证实验 Blum’s Book: Sample programs in Chapter 04, 05 (Moving Data)
实验准备
考虑用图形界面好看的Ubuntu,上官网下载Ubuntu20.04LIS,下载VMware15.0,并安装虚拟机。
安装gcc与make,顺便安装g++
$ sudo apt install gcc -y
$ sudo apt install make -y
$ sudo apt install g++ -y
第一次安装失败。更新apt
$ sudo apt-get update
后网速太慢,更改虚拟机内存,Ubuntu换源后均没有改善
安装GNU Binutils,上官网下载binutils-2.32.tar.gz,解压
$ tar zxvf binutils-2.32.tar.gz
配置binutils,编译与安装
$ cd binutils-2.32
$ ./configure
$ cd binutils-2.32
$ make && make install
安装32位库
$ sudo apt-get update
$ sudo apt install lib32z1 lib32ncurses5 g++-multilib libc6-dev-i386
解压 Blum-chap04-05.tgz,得到汇编代码
技术准备
.s 为汇编文件,.o为二进制文件,可执行文件没有后缀。
ls(list files)命令用于显示指定工作目录下之内容
as 命令用于将汇编代码编译为二进制代码,如as test.s -o test.o
ld命令用来将多个目标代码连接成一个可执行文件如 ld -o cpuid cpuid.o
运行可执行文件命令:./cpuid
调试前可带上gstabs,可在目标代码中加符号表$ as --gstabs -o xxxx.o xxxx.s
gdb xxxx
进入gdb调试
break *_start:在程序开始处设置断点
break * label+offset 设置断点,offset为相对位置
break 行号
break *end:在程序结束处设置断点
run:运行程序至断点
step/s/next/n:单步调试程序
cont:继续运行至断点
info registers:显示全部寄存器的值
print:显示某一寄存器或变量的值
print/d:显示十进制的值
print/t:显示二进制的值
print/x:显示十六进制的值
x/nyz:显示特定内存位置的值,n是要显示的字段数,y是输出格式,z是要显示字段的长度
实验过程
程序一:cpuid.s
as -o cpuid.o cpuid.s
ld -o cpuid cpuid.o
./cpuid
用gdb调试
as -gstabs -o cpuid.o cpuid.s
ld -o cpuid cpuid.o
gdb cpuid
能成功调试。
程序二:cpuid2.s
用32位系统动态链接
as --32 -o cpuid2.o cpuid2.s
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o cpuid2 -lc cpuid2.o
./cpuid2
报了warning,原因未知
程序三:sizetest1.s
as -o sizetest1.o sizetest1.s
ld -o sizetest1 sizetest1.o
ls -al sizetest1
能成功运行
程序四:sizetest2.s
as -o sizetest1.o sizetest1.s
ld -o sizetest1 sizetest1.o
ls -al sizetest1
可成功运行
程序五:sizetest3.s
as -o sizetest3.o sizetest3.s
ld -o sizetest3 sizetest3.o
ls -al sizetest3
可成功运行
程序六:movetest1.s
as -gstabs -o movtest1.o movtest1.s
ld -o movtest1 movtest1.o
gdb -q movtest1
调试结果符合预期
程序七:movetest2.s
as -gstabs -o movtest2.o movtest2.s
ld -o movtest2 movtest2.o
gdb -q movtest2
可见数值发生了交换
程序八:movetest3.s
as --32 -gstabs -o movtest3.o movtest3.s
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -lc -o movtest3 movtest3.o
./movtest3
能成功运行
程序九:movetest4.s
as -gstabs -o movtest4.o movtest4.s
ld -o movtest4 movtest4.o
gdb -q movtest4
程序十:cmovetest.s
as --32 -gstabs -o cmovtest.o cmovtest.s
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -lc -o cmovtest cmovtest.o
./cmovtest
程序十一:swaptest.s
as --gstabs -o swaptest.o swaptest.s
ld -o swaptest swaptest.o
gdb -q swaptest
可见swap后二进制位发生了交换。
程序十二:bubble.s
as -gstabs -o bubble.o bubble.s
ld -o bubble bubble.o
gdb -q bubble
程序十三:pushpop.s
as --32 -gstabs -o pushpop.o pushpop.s
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -lc -o pushpop pushpop.o
gdb -q pushpop