配置基于容器的的汇编环境

栏目: 编程语言 · 发布时间: 4年前

内容简介:使用命令执行过程以及结果:

使用 dockeralpine image 来做汇编的开发实验环境是很方便的,因为 docker 默认提供的是一个 x86-64 架构的Linux kernel,所以用来编译运行64bit的汇编代码十分方便。本文介绍使用方法。首先是从docker hub上面把 alpine linux 这个image给pull下来,然后运行 sh

$ docker run -it alpine sh

命令执行过程以及结果:

配置基于容器的的汇编环境

可以看到我们下载了 alpine 并且创建了容器,并在容器内部运行了 sh 。之所以要使用 alpine 这个 linux 发行版,是因为它非常小,只有 5.53mb

配置基于容器的的汇编环境

进入到 alpine linux 里面以后,把 vimyasm 安装好:

$ apk add vim yasm

下面是安装过程:

配置基于容器的的汇编环境

其中, vim 是常用的文本编辑器, yasm 是编译汇编代码的工具。此外,我们还要安装 gcc

$ apk add gcc

安装 gcc 的目的是为了把汇编与c相关的 工具 集都安装好。 gcc 的工具包比较大,所以下载安装过程需要耐心等待:

配置基于容器的的汇编环境

以上是环境的准备过程,接下来我们写一段汇编代码试试看:

global _start
_start:
  mov eax, 1
  mov ebx, 5
  int 0x80

上面的汇编代码就是简单地执行 syscall (通过调用 0x80 中断)的 exit ,然后返回值设定为 5 。我们把它保存为 foo.asm ,然后编译:

$ yasm -f elf64 -g dwarf2 -l foo.lst foo.asm

编译完成后会生成 .lst.o 文件;

$ ls
foo.asm  foo.lst  foo.o

其中 lst 为符号文件:

$ cat foo.lst
     1                                 %line 1+1 foo.asm
     2                                 _start:
     3 00000000 B801000000              mov eax, 1
     4 00000005 BB05000000              mov ebx, 5
     5 0000000A CD80                    int 0x80

如上所示, lst 文件标注了汇编代码对应的机器码和内存的 offset ,这个文件是给人看的,也可以不生成。所谓内存offset,就是代码的相对地址,而不是绝对地址。绝对地址要在代码被link成可执行代码后,由 linker 负责分配。linux下的 linker 一般是 ld 这个命令,我们来使用它把 .o 文件给链接成可执行代码;

$ ld -o foo foo.o

此时我们就得到了 foo 这个可执行文件。此时运行 foo ,并查看它的返回值:

配置基于容器的的汇编环境

可以看到程序的返回值为 5 。此时我们使用 objdump 命令查看生成的可执行文件的汇编代码:

$ objdump -Mintel -d foo

在上面的命令当中, -Mintel 是让 objdump 显示intel格式的汇编代码,默认是 at&t 格式的汇编代码,个人习惯看 intel 格式的。然后 -d 选项是显示程序的汇编代码。它和大写 -D 选项的区别如下:

-d, --disassemble        Display assembler contents of executable sections
-D, --disassemble-all    Display assembler contents of all sections

可以看到, -d 只显示主程序的sections的汇编代码,而 -D 显示所有的sections的代码,包括 debug 信息等等一大堆sections。下面是 objdump 的执行结果:

配置基于容器的的汇编环境

可以看到,编译后的代码的 .text 程序段,它的汇编代码基本就是我们手写的汇编代码,只不过是程序的内存地址被分配好了逻辑地址,这就是 linker 帮我们做的。比较一下 .lst 文件里的机器码和内存地址offset:

配置基于容器的的汇编环境

可以看到机器码完全一致,然后内存地址的offset关系一致,只不过编译链接后的代码的地址变成了process的逻辑地址。此外,我们可以看到直接手写的汇编代码,编译出来的代码量非常小,几乎就是对应我们手写的汇编代码。而 c 编译出来的代码,汇编指令会复杂很多,因为它包含了标准c库的很多接口指令,而且是 c语言 标准库 libc 负责接管跟linux kernel打交道,而不是像我们这样使用 int 0x80 的kernel system call直接调用内核接口。

以上就是对基于容器的汇编环境的使用介绍。接下来回过头讲讲这个容器。我们一开始是用 docker run 指令下载了 alpine 的image并且创建了一个容器并执行。但是我们后续希望继续使用这个容器,而不是再用 run 命令创建一个新的容器。所以后续再启动这个容器的时候,就要用 docker start 命令。首先是查看这个容器的 id

$ docker ps -a

下面是执行结果:

配置基于容器的的汇编环境

可以看到这个容器的 idc27a1e74e773 ,容器的名字为 sleepy_wu 。我们可以使用容器的 id 或者 name 来启动或停止这个容器。比如停止这个容器:

$ docker stop sleepy_wu

启动这个容器:

$ docker start sleepy_wu

启动这个容器以后,使用 exec 命令登录进这个容器的终端:

$ docker exec -it sleepy_wu sh

以上这些命令的执行全过程如下:

配置基于容器的的汇编环境

以上就是初步需要掌握的一些知识点。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

引爆点

引爆点

[美] 马尔科姆·格拉德威尔 / 钱清、覃爱冬 / 中信出版社 / 2006-1 / 29.80元

这本书是《纽约客》杂志专职作家马尔科姆·格拉德威尔的一部才华横溢之作。他以社会上突如其来的流行风潮研究为切入点,从一个全新的角度探索了控制科学和营销模式。他认为,思想、行为、信息以及产品常常会像传染病爆发一样,迅速传播蔓延。正如一个病人就能引起一场全城流感;如果个别工作人员对顾客大打出手,或几位涂鸦爱好者管不住自己,也能在地铁里掀起一场犯罪浪潮;一位满意而归的顾客还能让新开张的餐馆座无虚席。这些现......一起来看看 《引爆点》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试