GCC 和 NASM 联合编译

为了学习的顺利进行,今天尝试复习 C 语言和汇编语言的联合编译。代码很简单:

/* main.c */

extern void Print1();

char strFormat[] = "x = %d, y = %d, x + y = %d";

int main()
{
    Print1();

    return 0;
}
; proc.nas

extern printf
extern strFormat

global Print1

[SECTION .data]
	nX dd 14
	nY dd 23

[SECTION .text]
Print1:
	mov eax, [nX]
	mov ebx, [nY]
	mov ecx, eax
	add eax, ebx

	; 注意参数入栈顺序:从右向左
	push dword eax			; nX + nY
	push dword ebx			; nY
	push dword ecx			; nX
	push dword strFormat
	call printf

	add esp, byte 4 * 4
	ret
    #MakeFile
    
    nasm -felf32 proc.nas
    gcc -m32 -o main main.c proc.o

依然采用 GCC + NASM,可以通过编译,可是链接成执行文件怎么都通不过,一直报错“未定义函数”!

尝试各种操作系统(WinXP 32位、Win7 64位)、各种编译器版本(MinGW 32 位、64 位)、各种编译参数,搞了大半天,死活不让我过!

就在快绝望的时候,突然想起以前浏览的 C 语言库函数,依稀记得函数名前面都带有个下划线 “_”!是不是就是这个原因呢?试试。。。。。。

extern _printf
extern _strFormat

global _Print1

[SECTION .data]
	nX dw 14
	nY dw 23

[SECTION .text]
_Print1:
	mov eax, [nX]
	mov ebx, [nY]
	mov ecx, eax
	add eax, ebx

	; 注意参数入栈顺序:从右向左
	push dword eax			; nX + nY
	push dword ebx			; nY
	push dword ecx			; nX
	push dword _strFormat
	call _printf

	add esp, byte 4 * 4
	ret

竟然真是的,编译通过了!

总结,汇编语言(NASM)和 C 语言(GCC)联合编译的时候(在 Windows 系统下),汇编代码中和 C 语言产生混编关系的变量和函数,前面都要加一个下划线“_”!C 语言代码中不加。

时间: 2024-10-02 20:34:58

GCC 和 NASM 联合编译的相关文章

GCC 4.8.2 编译安装

https://my.oschina.net/u/728245/blog/184550 摘要: GCC 4.8.2 在 CentOS 6.5 下编译安装小记,遇到一些问题并解决. 以前从没有升级过GCC,一直用系统默认的GCC版本,最近在研究好久没有用过的 C, 便有了升级GCC的想发,大致如下. 环境: CentOS-6.5-i386 , gcc-4.4.7 系统必须已经安装有一个编译器,因为 gcc 也是需要编译的 首先 gcc 编译需要三个额外库,下载并按照下面的顺序安装它们,如下:1.

gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解

摘自http://blog.csdn.net/elfprincexu/article/details/45043971 gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解 C和C++编译器是集成的,编译一般分为四个步骤: 预处理(preprocessing)  ----------------- cpp/ gcc -E  编译(compilation) ------------------ cc1 / gcc -S 汇编(assembly)  ----------------

gcc/g++ 实战之编译过程

gcc和g++分别是GNU(一个开源组织)的c&c++编译器 对于.c后缀的文件,gcc把它当做是C程序,g++当做是C++程序:对于.cpp后缀的文件,gcc和g++都会当做c++程序.gcc可以根据后缀名为.c或.cpp分别按c程序和c++程序来编译,但是g++无论是.c或.cpp都统一按c++程序来编译. 编译阶段,g++会调用gcc,链接阶段通常会用g++来完成,g++在编译的过程中,其实是调用gcc按照c++程序来编译的.即编译工作最终都是由gcc来完成的.这是因为gcc命令不能自动和

coreseek 在gcc 4.9+ 上编译不通过 [sphinxexpr.o] Error 1 错误解决方案

这几天玩hhvm,把gcc环境都装到4.9了,然后编译coreseek的时候就出问题,google一大圈,貌似捕风捉影看到一些信息说是gcc4.7+的c++作用域必须用this->去引用,这里整理一个补丁仅供大家参考coreseek 在gcc 4.7+ 上编译不通过 [sphinxexpr.o] Error 1 错误解决方案 错误如下:(每个人环境都不太一样,提示错误信息应该不尽相同但出错原因应该都是gcc4.7+以上版本作用域的问题) sphinxexpr.cpp:1047:43: note:

【嵌入式开发】gcc 学习笔记(一) - 编译C程序 及 编译过程

一. C程序编译过程 编译过程简单介绍 : C语言的源文件 编译成 可运行文件须要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (assembly) 得到机器码, 连接 (linking) 得到可运行文件; -- 查看每一个步骤的编译细节 : "-E" 相应 预处理, "-S" 相应 编译, "-c" 相应 汇编, "-O" 相应 连接; -- 每一个步骤

gcc 学习笔记(一) - 编译C程序 及 编译过程

一. C程序编译过程 编译过程简介 : C语言的源文件 编译成 可执行文件需要四个步骤, 预处理 (Preprocessing) 扩展宏, 编译 (compilation) 得到汇编语言, 汇编 (assembly) 得到机器码, 连接 (linking) 得到可执行文件; -- 查看每个步骤的编译细节 : "-E" 对应 预处理, "-S" 对应 编译, "-c" 对应 汇编, "-O" 对应 连接; -- 每个步骤对应的工

【C/C++学院】0823-静态联合编译与动态联合编译/父类指针子类指针释放/虚函数/纯虚函数概念以及虚析构函数/抽象类与纯虚函数以及应用/虚函数原理/虚函数分层以及异质链表/类模板的概念以及应用

静态联合编译与动态联合编译 #include <iostream> #include <stdlib.h> //散列 void go(int num) { } void go(char *str) { } //class //::在一个类中 class A { public: void go(int num) { } void go(char *str) { } }; void main() { ///auto p = go;编译的阶段,静态联编 void(*p1)(char *s

VS2013使用VS2008的联合编译进行工程编译

公司开发C++是使用vs2008,编译的时候使用联合编译IncreBuild进行编译:在vs2008中使用visual assistx,如果代码太长,滚动的时候偶尔会出现页面乱码,而且有时候虚函数互相定位也有问题,没有vs2013使用方便,但是在vs2013中又不能直接编译,所有寻思做个插件解决编译问题: 因为工程文件都是使用vc9生成的,所有使用vs2013打开时,会自动进行工程升级,升级完成后,vc9和vs2013的工程会同时存在,如果想在vs2013中调用vs2008的编译器进行编译,可以

gcc/g++ 实战之编译的四个过程

gcc和g++分别是GNU(一个开源组织)的c&c++编译器 对于.c后缀的文件,gcc把它当做是C程序,g++当做是C++程序:对于.cpp后缀的文件,gcc和g++都会当做c++程序.gcc可以根据后缀名为.c或.cpp分别按c程序和c++程序来编译,但是g++无论是.c或.cpp都统一按c++程序来编译. 编译阶段,g++会调用gcc,链接阶段通常会用g++来完成,g++在编译的过程中,其实是调用gcc按照c++程序来编译的.即编译工作最终都是由gcc来完成的.这是因为gcc命令不能自动和