C++ 转换为C++;到C
假设我将一个C++ 转换为C++;到C,c++,c,decompiling,C++,C,Decompiling,假设我将一个c++程序编译成一个程序集(.S)文件 然后我把那个汇编文件“分解”成C,那个代码可以在不同的平台上重新编译吗 我问这个问题的原因是,我试图开发的平台没有c++编译器,因为它确实有c编译器。是的,按照您描述的方式,这确实是可能的。不,它不会移植到除您之外的任何CPU体系结构、操作系统和编译器三元组 让我们看看原因。采取一些基本的C++代码…< /P> #include <iostream> int main() { std::cout << "Hel
c++
程序编译成一个程序集(.S
)文件
然后我把那个汇编文件“分解”成C
,那个代码可以在不同的平台上重新编译吗
我问这个问题的原因是,我试图开发的平台没有
c++
编译器,因为它确实有c
编译器。是的,按照您描述的方式,这确实是可能的。不,它不会移植到除您之外的任何CPU体系结构、操作系统和编译器三元组
让我们看看原因。采取一些基本的C++代码…< /P>
#include <iostream>
int main()
{
std::cout << "Hello, world!\n";
return 0;
}
结果是
.file "test.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "Hello, world!\n"
.section .text.unlikely,"ax",@progbits
.LCOLDB1:
.section .text.startup,"ax",@progbits
.LHOTB1:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB1027:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE1027:
.size main, .-main
.section .text.unlikely
.LCOLDE1:
.section .text.startup
.LHOTE1:
.section .text.unlikely
.LCOLDB2:
.section .text.startup
.LHOTB2:
.p2align 4,,15
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1032:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
addq $8, %rsp
.cfi_def_cfa_offset 8
jmp __cxa_atexit
.cfi_endproc
.LFE1032:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .text.unlikely
.LCOLDE2:
.section .text.startup
.LHOTE2:
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_main
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.hidden __dso_handle
.ident "GCC: (GNU) 5.3.1 20151207 (Red Hat 5.3.1-2)"
.section .note.GNU-stack,"",@progbits
这就是我们为异常处理、模板和名称空间所付出的代价。让我们手动将其分解为C,丢弃异常处理表以获得更清晰的视图
/* std::ostream */
typedef struct
{
/* ... */
} _ZSo;
/* extern operator<<(std::basic_ostream&, const char*); */
extern _ZStlsIst11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc();
/* namespace std { extern ostream cout; } */
extern _ZSo _ZSt4cout;
/* Our string, of course! */
static const char* LC0 = "Hello, world!\n";
int main()
{
_ZStlsIst11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(&_ZSt4cout, LC0);
return 0;
}
/*std::ostream*/
类型定义结构
{
/* ... */
}_ZSo;
/*外部运算符如果dis汇编程序提供有效的c代码,为什么不提供?但首先需要验证它是否提供了有效的c代码。@SHR我担心的是它会将uint16\u t
s转换为uint8\u t
s之类的东西that@DarthRubik请注意,这可能是一个更好的解决方案:没有从汇编到C的定义良好的映射。您必须明确说明汇编得到了什么“disassembled”使用什么工具。一般来说:不要使用未在目标平台上实现的编程语言。如果我不使用任何库并自己编写所有内容(没有printfs或couts),该怎么办?@DarthRubik:根据定义,标准库的实现是不可移植的。您将如何以完全可移植的方式实现printf
本身?不可能。这就是为什么标准库首先存在的原因;它们为所有不同的平台提供了一个通用的、可移植的接口。不管怎样,你仍然需要处理异常处理之类的事情。这是一个微控制器(所以我根本不会有任何printfs),在微控制器上我根本不会抛出异常ever@DarthRubik字体哦,太好了。因此,如果您处于嵌入式环境中,就不应该太在意可移植性。在这种情况下,只需手工重写代码即可。如果没有C++编译器,你可能连C标准库都没有,不是吗?
/* std::ostream */
typedef struct
{
/* ... */
} _ZSo;
/* extern operator<<(std::basic_ostream&, const char*); */
extern _ZStlsIst11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc();
/* namespace std { extern ostream cout; } */
extern _ZSo _ZSt4cout;
/* Our string, of course! */
static const char* LC0 = "Hello, world!\n";
int main()
{
_ZStlsIst11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(&_ZSt4cout, LC0);
return 0;
}