3

我想知道是否有办法调用 .c 汇编代码?我想将此代码放在我的 .c 文件中

我想在 .c 文件中执行的汇编代码以返回地址

1. mov eax, 0x2d
2. mov ebx, 0
3. int 0x80

我知道答案是 put eax。

这是 .c 文件的一部分:

1. void function(void)
2. {
3. void *sp;
4. sp = eax;
5. fprintf(stderr, "system break:   %p\n", sp);
6. }

我该怎么做?

4

5 回答 5

7

执行此操作的能力是特定于编译器的。Gcc使用其asm关键字 extension允许这样做,而 Visual Studio 实现了不同的扩展

请注意,除了不可移植到其他架构的明显问题之外,包括任何内联汇编都会降低性能,因为编译器无法分析汇编以确定它是否无副作用、内联是否安全、是否访问全局资源, 等等。

于 2012-11-03T08:36:11.020 回答
3

一些编译器将__asm__orasm关键字实现为 C 语言的扩展:

__asm__(
    "mov eax, 0x2d\n"
    "mov ebx, 0\n"
    "int 0x80\n"
);

括号中的代码将被逐字复制到汇编程序的输入中。更多关于 GCC 如何实现这个特性的文档,可以在这里找到。

顺便说一句,如果你想改变堆栈指针的值(为什么?),你可以在一行中完成:

__asm__("mov esp, eax");
于 2012-11-03T08:36:48.757 回答
3

如果例如使用 gcc,另一种方法是首先编译一些非常琐碎的函数而不进行优化:

int foo(int a, int b) {
  return a+(b<<3);
}

gcc -S foo.c

并使用 foo.s 作为模板。稍后可以编译并链接这些文件 gcc main.c foo.s(并确保删除 foo.c 文件/将 foo.s 重命名为其他文件)

从该特定函数可以观察到,编译器将结果放在哪里,以及编译器将第一个和第二个参数放在哪个地址或寄存器中。

它比使用读、写、破坏列表学习 asm 模板要快一些。

于 2012-11-03T08:58:54.540 回答
2

您真的需要将 Nasm 语法中的 asm 源代码“放入”您的 C 源程序吗?弗格编辑。lcc 也许......如果你想从你的 C 程序“执行”你的 asm 程序......

    global getbrk
    section .text
    getbrk:
        push ebx ; C likes it saved
        mov eax, 45 ; __NR_brk
        xor ebx, ebx ; get current break
        int 80h
        pop ebx
        ret

assemble nasm -f elf getbrk.asm,放入sp=getbrk();你的C文件,编译gcc -m32 -O3 -o myprog myprog.c getbrk.o

或者只是sp=sbrk(0);在你的 C 程序中跳过 asm... 不会比使用 int 80h 更便携。(但那会有什么乐趣呢?):)

于 2012-11-03T10:49:28.530 回答
2
void function(void){

   void *sp
   __asm__ volatile(
   "movl $0x2d, %%eax;"
   "movl $0, %%ebx;"
   "int $0x80"
   :"=a"(sp)
   :
   :"%ebx"
   );

   fprintf(stderr, "system break: %p\n",sp);
   }

这是我的答案:)

于 2012-11-04T21:55:38.003 回答