gpt4 book ai didi

linux - 是否可以使用 `as` 组装和运行原始 CPU 指令?

转载 作者:太空狗 更新时间:2023-10-29 11:24:44 24 4
gpt4 key购买 nike

这里有几个相关的问题。考虑一个仅由以下两条指令组成的程序

movq 1, %rax
cpuid

如果我将其放入名为 Foo.asm 的文件中,然后运行 ​​as Foo.asm,其中 as 是可移植的 GNU 汇编器,我将在我的系统上得到一个名为 a.out 的文件,大小为 665 字节。

如果我然后 chmod 700 a.out 并尝试 ./a.out,我会得到一个错误提示 cannot execute binary file .

  1. 如果我只是想将两个 asm 指令翻译成二进制文件,为什么文件这么大?
  2. 为什么二进制文件不能执行?我提供的是有效指令,因此我希望 CPU 能够执行它们。
  3. 如何在我的输入文件中获取 asm 指令的二进制操作码,而不是一堆额外的东西?
  4. 一旦我得到了问题 3 的答案,我怎样才能让我的处理器执行它们? (假设我没有运行特权指令。)

最佳答案

  1. 如果我只是想将两个 asm 指令翻译成二进制,为什么文件这么大?

    因为汇编程序创建了一个 relocatable object file其中包括附加信息,例如内存部分符号表

  2. 为什么二进制执行不了?

    因为它是一个(可重定位的)目标文件,而不是一个可加载文件。您需要链接它以使其可执行,以便操作系统可以加载它:

    $ ld  -o Foo a.out

    您还需要通过指定 _start 符号向链接器提示您的程序从何处开始。

    但是,Foo 可执行文件仍然比您预期的要大,因为它仍然包含操作系统实际需要的额外信息(例如 elf header)启动程序。

    此外,如果您现在启动可执行文件,它会导致段错误,因为您正在加载地址 1 的内容,它没有映射到您的地址空间,进入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
  3. 我怎样才能在我的输入文件中获得 asm 指令的二进制操作码,而不是一堆额外的东西?

    • You can use objcopy目标文件生成原始二进制图像:

      $ objcopy -O binary a.out Foo.bin

      然后,Foo.bin包含指令操作码。

    • nasm有一个 -f bin 选项,它可以创建汇编代码的二进制表示。我用它来实现 bare boot loader for VirtualBox (警告:未记录,仅原型(prototype)!)在没有操作系统的情况下直接在 VirtualBox 镜像中启动二进制代码。

  4. 一旦我得到了问题 3 的答案,我怎样才能让我的处理器执行它们?

    您将无法在 Linux 下直接执行原始二进制文件。您将需要为此编写自己的加载程序,或者根本不使用操作系统。例如,请参阅上面我的裸引导加载程序链接 - 这会将操作码写入 VirtualBox 光盘镜像的引导加载程序,以便在启动 VirtualBox 机器时执行指令。

关于linux - 是否可以使用 `as` 组装和运行原始 CPU 指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22376285/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com