آشنایی با مراحل کامپایل کد سی در گنو

اگر با کامپایلر زبان سی در لینوکس یا همان GNU C Compiler آشنایی دارید احتمالا از دستور زیر برای گرفتن خروجی از کدتان استفاده کرده اید:

gcc -o myapp mycode.c

 این دستور به صورت خلاصه تمام کارهای لازم جهت کامپایل و لینک و … را برای تولید خروجی برنامه مورد نظر ما انجام میدهد.

اما راه هایی که واقعا طی میشود تا کد خام زبان سی ما تبدیل به برنامه خروجی شود چیست؟ در این مطلب تعدادی از این مراحل را به تفکیک انجام میدهیم تا با این مراحل بیشتر آشنا شویم.

فرض کنید برنامه ما شامل ۲ فایل به صورت زیر است:

#include <stdio.h>
#include "myheader.h"

void myFun(void){
	printf("Hello Compiler!");
}
int main(){
	myFun();
	return OK;
}

و

#define OK 0
void myFun(void);

 کامپایلر c قبل از اینکه کدی به زبان سی را کامپایل کند با استفاده از دستورات پیش پردازنده نوشته شده در کد، خروجی کاملتری را تولید میکند. مثلا فایل هایی که include کرده ایم را به خروجی اضافه میکند و یا ماکروهایی که نوشته ایم را در محل های صحیح آن جایگزین میکند. نتیجه انجام این کار خروجی جدیدی است که کامپایلر آن را خط به خط کامپایل میکند. اگر بخواهیم این مرحله از انجام کار را به صورت جداگانه مشاهده کنیم میتوانیم از دستور زیر استفاده کنیم:

cpp mycode.c

این دستور خروجی تولید شده بعد از اجرای دستورات پیش پردازنده را بر روی صفحه نمایش به ما نشان میدهد. اگر بخواهیم این خروجی را در فایلی برای انجام مراحل بعدی کامپایل ذخیره کنیم از دستور زیر استفاده میکنیم:

gcc mycode.c > mycode.i

کامپایلر های زبان سی قبل از تولید کد ماشین ابتدا کد زبان اسمبلی را میسازند و سپس از روی آن کد به کد ماشین مقصد میرسند. اگر از خودتان میپرسید که چرا مستقیما کد ماشین تولید نمیشود جواب شما در منابع مربوط به طراحی کامپایلرها نهفته است. در واقع این کار نوشتن کامپایلرها را ساختیافته تر، کوتاه تر و ساده تر میکند.

gcc -S mycode.i

خروجی دستور بالا فایلی به نام mycode.s است. این فایل را با یک text editor مثل notepad باز کنید. محتویات فایل چیزی شبیه به این است:

	.file	"mycode.c"
	.section .rdata,"dr"
LC0:
	.ascii "Hello Compiler!\0"
	.text
.globl _myFun
	.def	_myFun;	.scl	۲;	.type	۳۲;	.endef
_myFun:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$۸, %esp
	movl	$LC0, (%esp)
	call	_printf
	leave
	ret
	.def	___main;	.scl	۲;	.type	۳۲;	.endef
.globl _main
	.def	_main;	.scl	۲;	.type	۳۲;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$۸, %esp
	andl	$-۱۶, %esp
	movl	$۰, %eax
	addl	$۱۵, %eax
	addl	$۱۵, %eax
	shrl	$۴, %eax
	sall	$۴, %eax
	movl	%eax, -4(%ebp)
	movl	-۴(%ebp), %eax
	call	__alloca
	call	___main
	call	_myFun
	movl	$۰, %eax
	leave
	ret
	.def	_printf;	.scl	۳;	.type	۳۲;	.endef

 همانطور که میبینید این یک کد به زبان اسمبلی است که از کد زبان سی که ما نوشته ایم ساخته شده است.

در اینجا نوبت به Assembler میرسد. کار اسمبلر تولید کد ماشین از کد اسمبلی است:

as -o mycode.o mycode.s

 این دستور فایل mycode.o که فایل حاوی دستورات زبان ماشین است را تولید میکند.

مرحله پایانی، مرحله لینک فایل های آبجکت و تولید فایل اجرایی است. این مرحله توسط Linker انجام میشود.

 ld -o mycode.o other_libraries

 Linker فایل های آبجکت و در صورت لزوم کتابخانه های static (فایل های با پسوند a) و کتابخانه های shared (فایل های so) را برای تولید فایل اجرایی به هم پیوند میدهد. البته باید توجه داشته باشیم که برنامه های نوشته شده به زبان سی حداقل به کتابخانه های استاندارد این زبان برای تولید فایل اجرایی نیاز دارند. کتابخانه هایی که متدهای استاندارد این زبان مثل (abs, printf , …) را پیاده سازی کردند. این کتابخانه ها وقتی از روش خلاصه که در ابتدای بحث نوشتیم استفاده کنیم به صورت اتوماتیک به برنامه ما لینک میشوند ولی در صورتی که بخواهیم از ld استفاده کنیم باید صریحا آنها را وارد کنیم.

در تصویر زیر انجام این مراحل را به اختصار مشاهده می کنید:

ccompilersteps2

اشاره: برای اجرای دستورات بالا در ویندوز میتوانید از محیط های شبیه سازی لینوکس در ویندوز مثل cygwin و MinGW استفاده کنید.

 

منبع: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html

برنامه‌نویس ++‏C/C‏ - برنامه‌نویس سیستم‌های گرافیکی با استفاده از کتابخانه ‏OpenGL - برنامه‌نویس #‏C و ..‏

5 thoughts on “آشنایی با مراحل کامپایل کد سی در گنو

  1. با سلام
    برنامه کوتاه نوشتم چگونه خروجی بگیرم و
    لطفا طرز گرفتن فایل exe را توضیح دهید
    با تشکر

    1. سلام با دستوری که ابتدای این پست قرار دادم در یک مرحله فایل اجرایی ساخته میشه. البته باید توجه کنید که اگه در ویندوز دارید این کار رو انجام میدید باید از cygwin یا mingw استفاده کنید.

  2. سلام آقا مجتبی
    به نظر من علاقه مهمترین فاکتور برای انتخاب رشته و کار آیندس. اگر در خودتون علاقه به موضوعات مربوط با رشته کامپیوتر میبینید و تلاش خودتون رو بکنید به نظر من فرصت های زیادی توی این حوزه برای کار هست.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

13 − هشت =

Back To Top