这里有几个相关的问题。考虑一个仅由以下两个指令组成的程序
movq 1, %rax
cpuid
如果将其放入一个名为的文件中Foo.asm
,然后运行便携式GNU汇编器as Foo.asm
(在哪里as
),我的系统上将得到一个名为的文件a.out
,大小为665字节。
如果我然后chmod 700 a.out
尝试./a.out
,我会得到一个错误的说法cannot execute binary file
。
asm
指令转换为二进制文件,为什么文件那么大?asm
在输入文件中准确获得指令的二进制操作码,而不是一堆额外的东西?如果我仅尝试将两个asm指令转换为二进制文件,为什么文件那么大?
因为汇编程序会创建一个relocatable object file
包含其他信息的,例如内存Sections和Symbol table。
为什么二进制文件无法执行?
因为它是(可重定位的)object file
,而不是loadable file
。您需要链接它以使其可执行,以便操作系统可以加载它:
$ ld -o Foo a.out
您还需要通过指定_start
符号为链接程序提供有关程序从何处开始的提示。
但是,Foo
可执行文件仍然超出了您的预期,因为它仍然包含elf header
操作系统实际启动程序所需的其他信息(例如)。
另外,如果您现在启动可执行文件,则由于将未映射到地址空间1segmentation fault
的内容加载到中,因此将导致。不过,如果您解决此问题,该程序最终将运行在未定义的代码中-您需要确保通过正常退出该程序。address
rax
syscall
一个最小的运行示例(假设为x86_64体系结构)看起来像
.globl _start
_start:
movq $1, %rax
cpuid
mov $60, %rax # System-call "sys_exit"
mov $0, %rdi # exit code 0
syscall
如何在输入文件中准确获取asm指令的二进制操作码,而不是一堆多余的东西?
您可以用来objcopy
从目标文件生成原始二进制图像:
$ objcopy -O binary a.out Foo.bin
然后,Foo.bin
将仅包含指令操作码。
nasm有一个-f bin
选项,可以创建汇编代码的仅二进制表示形式。我用它为VirtualBox实现了一个裸启动加载程序(警告:未记录,仅原型!),无需操作系统即可直接在VirtualBox映像内启动二进制代码。
找到3的答案后,如何使我的处理器执行它们?
您将无法在Linux下直接执行原始二进制文件。您将需要为此编写自己的加载程序,或者根本不使用操作系统。例如,请参见上面的裸机引导程序链接-这会将操作码写入VirtualBox磁盘映像的引导程序中,以便在启动VirtualBox计算机时执行指令。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句