下面是从inject-bundle项目复制的c文件中的asm函数:
asm void mach_thread_trampoline(void)
{
// Call _pthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
// Call cthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
// Call function with return address and arguments already on stack
pop eax
jmp eax
}在gcc之后(我在mac os x lion 10.7.4上做这项工作):
$gcc -m32 -fasm blocks -o a a.c -g
gdb目标,查看gdb中的mach_thread_trampoline内容:
(gdb) x/17i mach_thread_trampoline
0x1f80 <mach_thread_trampoline>: pop %eax
0x1f81 <mach_thread_trampoline+1>: call *%eax
0x1f83 <mach_thread_trampoline+3>: mov %esp,%eax
0x1f85 <mach_thread_trampoline+5>: mov %eax,%esp
0x1f87 <mach_thread_trampoline+7>: add $0x4,%esp
0x1f8a <mach_thread_trampoline+10>: mov %esp,%eax
0x1f8c <mach_thread_trampoline+12>: mov %eax,-0x8(%ebp)
0x1f8f <mach_thread_trampoline+15>: pop %eax
0x1f90 <mach_thread_trampoline+16>: call *%eax
0x1f92 <mach_thread_trampoline+18>: mov %esp,%eax
0x1f94 <mach_thread_trampoline+20>: mov %eax,%esp
0x1f96 <mach_thread_trampoline+22>: add $0x4,%esp
0x1f99 <mach_thread_trampoline+25>: mov %esp,%eax
0x1f9b <mach_thread_trampoline+27>: mov %eax,-0x8(%ebp)
0x1f9e <mach_thread_trampoline+30>: pop %eax
0x1f9f <mach_thread_trampoline+31>: jmp *%eax
0x1fa1 <mach_thread_trampoline+33>: ret 目标为mach_thread_trampoline函数添加了一些指令。
有什么方法可以保持asm函数不变吗?
发布于 2018-08-06 01:51:31
使用gcc似乎无法做到这一点,但您可以在a.asm中编写该函数,并使用nasm汇编a.asm。a.asm看起来像这样:
[BITS 32]
global _mach_thread_trampoline
_mach_thread_trampoline:
; Call _pthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
; Call cthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
; Call function with return address and arguments already on stack
pop eax
jmp eax要在C中使用它,您需要包含以下内容的a.h:
void mach_thread_trampoline(void);请注意,该函数的初始标题为_mach_thread_trampoline in a.asm & mach_thread_trampoline in a.h。这是因为在OS上,函数名前面有一个下划线。如果你把它移到linux上,程序集也会有mach_thread_trampoline,因为linux不会在前面加上任何东西。
发布于 2018-08-06 03:59:17
如果你有非常重要的asm函数,你应该把它放在单独的.S文件中,如果你愿意,你可以在这里使用.intel_syntax noprefix,或者像另一个答案建议的那样使用NASM。
但是您可以在全局范围内使用asm("");语句来绕过任何编译But /怪异之处。如果您想将一个以GAS语法编写的小函数插入到.c或.cpp中,请参阅本答案的最后一节。
作为函数类型的asm似乎是苹果的扩展,它不支持(Linux) gcc或clang on the Godbolt编译器资源管理器。
看起来它和__attribute__ ((naked))的作用是一样的(主流(不仅仅是苹果)Clang3.3及更高版本,以及最近的GCC在x86上都支持它。但是@MichaelPetch报告说OSX10.7 (gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00))上的gcc不支持__attribute__ ((naked))。
(较新的OS X使gcc成为clang的别名,但较旧的OS X有自定义版本的GCC)。
您正在使用的编译器版本中的asm void func(void) {语法似乎有一个编译器错误;它假设存在一个帧点并插入像mov %eax,-0x8(%ebp)这样的东西,这是没有意义的。如果允许编译器这样做,我看不出asm扩展有什么用处。也许在-O3中不会发生这种情况,因此您可以通过启用优化来解决此问题。
顺便说一句,常规(非苹果)的GCC不支持MSVC风格的asm块,但是,只支持GNU C asm("instructions"); asm语句。但使用LLVM的苹果版本的gcc确实支持它。
__attribute__ ((naked)) ( OS X 10.7不支持,gcc)
如果你有一个错误的编译器,在asm块中引入额外的指令,IDK,如果这会有什么不同。(即使它受支持,但在OS X 10.7 gcc上不受支持)
这种语法适用于现代的clang。(不是gcc,因为还是不支持-fasm-blocks)
这将使用clang 3.3正确编译on Godbolt。我使用“二进制”输出来确保我看到的是目标文件中的真实机器代码,所以我必须使用-nostdlib将其链接起来。它避免了使用-O0或-O3扭曲您的asm,但我使用的是一个非常不同的编译器,这种语法更改可能与此无关。
__attribute__ ((naked)) void mach_thread_trampoline(void)
{
// asm block *inside* a function
asm {
// Call _pthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
// Call cthread_set_self with pthread_t arg already on stack
pop eax
call eax
add esp, 4
// Call function with return address and arguments already on stack
pop eax
jmp eax
}
}可移植的GNU C asm("");
在GNU中,可以将Basic ASM statements放在全局范围内。
这个语法可能会解决OS X 10.7上的编译器错误,因为我们根本没有使用-fasm-blocks,编译器也没有机会认为它在一个函数中。它应该只是在.text部分中汇编这段代码。
void mach_thread_trampoline(void); // prototype
// definition: name mangling / leading underscore must be done manually
asm(".globl _mach_thread_trampoline\n\t"
"_mach_thread_trampoline:\n\t"
"pop %eax\n\t"
"call *%eax\n\t"
...
"jmp *%eax"
);因此,裸函数在C++中可能具有优势,因为名称篡改不是微不足道的。可能裸函数是自动的非内联函数。
如果您想要真正的可移植性,您可以使用诸如jmp {*%eax|eax}之类的方言替代方案,这样,无论是否使用-masm=intel编译,您的代码都可以正常工作。
我不建议在asm块中使用.intel_syntax noprefix,然后在编译器的其余代码末尾切换回.att_syntax。如果你(或者像Godbolt编译器资源管理器这样的工具)用-masm=intel编译,这是一个破解的技巧。
https://stackoverflow.com/questions/11552669
复制相似问题