繁体   English   中英

获取 C 代码中 ASM 指令的字节表示

[英]Get byte representation of ASM instruction within C code

在 C 代码中,有没有办法将 ASM 指令的文本表示(如cmpwi r3, 0x20 )转换为其二进制表示( 0x2c030020 )?

我正在编写将在运行时嵌入到另一个应用程序中的代码。 该代码应该改变正在运行的程序的行为/代码。 这意味着,有一堆这样的代码行:

*((volatile int *)(0x80001234)) = 0x2c030020;

该代码将 ASM 指令cmpwi r3, 0x20写入 0x80001234,覆盖该地址处的当前指令。 现在,在我的 C 代码中使用常量“0x2c030020”而不知道它的作用对维护代码不利。 因此,我通常会在上面的代码中添加注释,说明 ASM 指令: // 2c 03 00 20 = cmpwi r3, 0x20

但是,这些有时会不同步。 我可能会快速更改整数值而忘记更新评论,或者我可能只是在评论中打错了字,从而导致混乱。

有什么办法可以让我做这样的事情吗? (伪代码) *((volatile int *)(0x80001234)) = asm("cmpwi r3, 0x20"); 这会导致 0x2c030020 被写入 80001234? 或者我是否需要一个带有自定义预处理器的 hacky 解决方案,在我的 C 源文件上运行,用它们的字节码替换 ASM 指令?

我知道有使用asm()函数的内联汇编代码的 C 语法,但这会执行给定的 ASM 指令,而不是给我它们的二进制表示。

这听起来像是一件疯狂的事情,但我认为您有充分的理由这样做。 生活没有一点点疯狂就没有乐趣。

您可以使用的一种方法是在构建期间使用汇编器来生成编译时常量。

第一步是制作一个文件,其中包含您将使用的每条汇编指令,每行一个。

例如:

cmpwi   3,0x20
addi    3,3,0
blr

将该文件命名为 input.def。 然后,使用这个 shell 脚本:

#!/usr/bin/env bash

(cat << HEADER
    .global main
    .text
main:
HEADER
cat input.def) > asm.s

powerpc-linux-gnu-as asm.s -o asm.o

powerpc-linux-gnu-objdump -d asm.o | \
    sed '1,/<main>/ d' | \
    paste -d'\t' - input.def | \
    awk -F'\t' '{
        bytes=$2
        asm=$4
        disasm=$3
        gsub(/ /, "", bytes);
        gsub(/[, ]+/, "_", asm);
        printf("#define ASM_%-20s 0x%s    // disassembly: %s\n", asm, bytes, disasm)
    }'

# Clean temporaries
rm asm.s asm.o

(我在这里使用 GNU 汇编程序和 objdump。如果您不使用这些工具,您可能需要更改这部分。objdump 在这里被用作一种美化的 hexdump 实用程序。)

这个shell脚本:

  1. 创建装配文件
  2. 组装它
  3. 与 input.def 并排放置。 (这样它就可以看到您键入的程序集。)
  4. 重新格式化十六进制,使其成为合法的 C 常量。 重新格式化 asm,使其成为合法的 C 符号。 然后,编写一个定义以将指令名称映射到常量。
  5. 将所有这些放在 asm.h 中

这是很多工作,但您可以在编译时完成所有工作。

这会生成一个名为 asm.h 的头文件:

#define ASM_cmpwi_3_0x20         0x2c030020    // disassembly: cmpwi   r3,32
#define ASM_addi_3_3_0           0x38630000    // disassembly: addi    r3,r3,0
#define ASM_blr                  0x4e800020    // disassembly: blr

您可以像这样使用 asm.h 文件:

#include "asm.h"
*((volatile int *)(0x80001234)) = ASM_cmpwi_3_0x20;

如果需要新的 asm 常量,请编辑 input.def 并重新运行 shell 脚本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM