mingw nasm c调用汇编 汇编调用c

说明:

  一直没实践过 c和汇编函数的互相调用,上网搜了一下,大体上是你抄我,我抄你. 抄的不亦乐乎.至于为什么该这样调用楞是屁也没放一个,给我广大程序员带来了多少困扰.今天自己实践了一下汇编和c的互相调用,当然遇到的困难不少,还好够机警总算解决了,也懂了不少!  严重鄙视网上的抄袭作风,真恶心.

 

汇编和c互相调用的原理:

  以下这些话都是我自己总结的,错误还望不吝赐教,当然本人不欢迎侮辱的赐教.

  要想汇编和c实现互调,必须要达到的第一步就是. asm汇编程序生成obj文件 c程序生成obj文件 .所谓的obj文件,就是所谓的链接文件,当然我们要做的就是链接这一步      了!!!

  要想正确的链接c和汇编的obj文件可不是件容易的事情,当然出错的重点大多都是在汇编里面.为什么呢?

  因为汇编里面所有的符号都是自己写的,而且生成obj以后的符号也不会变.但是c不同 c的函数 比如自定义 pt()生成obj文件后 打开obj文件一看 显示的是_pt.

  因此要想正确的链接两个obj就需要了解链接器(如 mingw)的习惯了.其实这个规律很简单!只要保证汇编程序里面的符号和c生成的obj里面的符号一致即可了.

  比如我asm定义MessageBoxA该符号,但是链接的时候是不通过的,因为(mingw)不认识该符号只认识_MessageBoxA@16.至于如何知道的 只需要在c中简单的调用一

      下MessageBoxA然后生成该c的obj,以16进制的方式打开该obj搜索MessageBoxA你就可以看到真正的符号是_MessageBoxA@16所以为了正确的链接汇编里面调用

      的符号必须和链接器要求的一致!

 

下面贴出简单的测试代码:

一  main.c:

#include <stdio.h>
#include<windows.h>

void message();//从汇编  中导出的函数 需要声明 才可以使用  当然不声明也可以使用 这是因为obj中有该符号 最好申明一下


//c函数 因为 c式的 函数 编译出函数 符号一般加 _ 所以 在汇编里显示为 _prt
//当然 如果不确定的话 可以打开编译的 .obj 链接文件 看看 符号的名字 一切 以.obj链接文件的符号为准 因为我们需要做的是链接这一步!!
void prt()
{
    printf("我是 c 函数  汇编调用输出成功 .... \n");
}


void main()
{
    message();//c调用的 汇编 函数 message 
    //MessageBoxA(0,"","",0); 如果不知道 MessageBoxA在汇编的符号 可以查看 该c中 obj的符号 这样的符号肯定是正确的了
}

 

二  message.asm

global _message             ; 从汇编中导出的函数 给c 使用
extern _MessageBoxA@16    ;导入api 注意符号的问题
extern _prt    ;从c中导入的函数

[section .data]     ; 数据在此

szTitle db  "我是标题 hello",0
szCon db "我是显示的内容",0

[section .text]             ; 代码在此

;global _main                ; exe入口函数,同样要加下划线 当然 入口函数也可以放在 asm 中 只要 link 可以识别即可
;当然 入口函数 可以放在 asm 中 也可以放在 c中 放在 asm需要 注意 符号的问题 毕竟每个编译器 需要的符号可能是不一样的 不能一味的死记

_message:   ;c 调用汇编 的函数  当然也得注意 调用约定的清栈 规则 否则很容易出错
push ebp
mov ebp,esp
push 0
push szTitle
push szCon
push 0
call _MessageBoxA@16
call _prt;此处     汇编 调用 c 函数
mov esp,ebp
pop ebp
ret

三  makefile

all:
    nasm -f win32 message.asm -o message.obj
    gcc -c main.c -o main.obj
    gcc  message.obj main.obj -o main.exe

clean :
    rm *.obj *.exe 

 

四  如何编译

  a.  首先 你得学会 nasm 该编译器和 基本的汇编语法 并编译成 win32 obj 文件

    b.  c程序 也得编译成obj文件

  c.  至于链接器如何选择 我选的是windows版的gcc编译器 mingw

  d.  当然还得需要解决错误的能力 和毅力

posted @ 2012-08-01 14:01  molixiaoge  阅读(2629)  评论(2编辑  收藏  举报