如何从汇编程序指令转到C代码

van*_*lfi 5 c assembly instruction-set instructions

我有一个任务,除其他外,我需要在.asm文件中查找某个指令和"反向工程"(找出)C代码的哪一部分导致它在汇编程序级别执行.(文字下方的例子)

什么是最快(最简单)的方法.或者更好地说,.asm文件中的其他命令/指令/标签应该/我可以注意什么,这将指导我使用正确的C代码?

我几乎没有使用汇编代码的经验,很难弄清楚C代码的确切行会导致特定指令发生.

如果这有任何区别,那么这个架构就是TriCore.

示例:通过跟踪使用变量的位置,我设法找出C代码在asm文件中导致插入的内容

 .L23:
    movh.a  a15,#@his(InsertStruct)
    ld.bu   d15,[a15]@los(InsertStruct)
    or  d15,#1
    st.b    [a15]@los(InsertStruct),d15
.L51:
    ld.bu   d15,[a15]@los(InsertStruct)
    insert  d15,d15,#0,#0,#1
    st.b    [a15]@los(InsertStruct),d15
.L17:
    mov d15,#-1
Run Code Online (Sandbox Code Playgroud)

这导致我得到以下C代码:

InsertStruct.SomeMember = 0x1u;

InsertStruct.SomeMember = 0x0u;
Run Code Online (Sandbox Code Playgroud)

Mar*_*nau 3

该架构是 TriCore(如果有什么区别的话)。

当然。汇编代码始终是特定于体系结构的。

... C 代码的哪一部分导致它在汇编程序级别上执行。

当使用高度优化的编译器时,你几乎没有机会:

例如,TriCore 的 Tasking 编译器有时甚至会为两个不同的 C 文件中的两行不同的 C 代码生成一个汇编代码片段(在内存中仅存储一次!)!

但是,您的示例中的代码未优化(除非您命名的结构InsertStructvolatile)。

在这种情况下,您可以在打开调试信息的情况下编译代码并提取调试信息:从 ELF 格式文件中,您可以使用诸如addr2line(GNU 编译器套件中的免费软件)之类的工具来检查哪一行 C 代码对应于某个指令某个地址。

(注意:该addr2line工具是独立于体系结构的,只要两种体系结构具有相同的宽度(32 位)、相同的字节序并且都使用 ELF 文件格式;您可以使用addr2lineARM 从 TriCore 文件获取信息。)

如果您确实必须理解汇编代码片段,我自己通常会执行以下操作:

我启动文本编辑器并粘贴汇编代码:

movh.a  a15,#@his(InsertStruct)
ld.bu   d15,[a15]@los(InsertStruct)
or      d15,#1
st.b    [a15]@los(InsertStruct),d15
...
Run Code Online (Sandbox Code Playgroud)

然后我将每条指令替换为等效的伪代码:

a15 =  ((((unsigned)&InsertStruct)>>16)<<16;
d15 =  *(unsigned char *)(a15 + (((unsigned)&InsertStruct)&0xFFFF));
d15 |= 1;
*(unsigned char *)(a15 + (((unsigned)&InsertStruct)&0xFFFF)) = d15;
...
Run Code Online (Sandbox Code Playgroud)

在下一步中,我尝试简化此代码:

a15 =  ((unsigned)&InsertStruct) & 0xFFFF0000;
Run Code Online (Sandbox Code Playgroud)

然后:

d15 = *(unsigned char *)((((unsigned)&InsertStruct) & 0xFFFF0000) + (((unsigned)&InsertStruct)&0xFFFF));
...
Run Code Online (Sandbox Code Playgroud)

然后:

d15 = *(unsigned char *)((unsigned)&InsertStruct);
...
Run Code Online (Sandbox Code Playgroud)

然后:

d15 = *(unsigned char *)&InsertStruct;
...
Run Code Online (Sandbox Code Playgroud)

最后我尝试替换跳转指令:

d15 = 0;
if(d14 == d13) goto L123;
d15 = 1;
L123:
Run Code Online (Sandbox Code Playgroud)

... 变为:

d15 = 0;
if(d14 != d13) d15 = 1;
Run Code Online (Sandbox Code Playgroud)

...最后(也许):

d15 = (d14 != d13);
Run Code Online (Sandbox Code Playgroud)

最后,文本编辑器中就有了 C 代码。

不幸的是,这需要很多时间 - 但我不知道有什么更快的方法。