🌱 GCC Commands trong Build Process chương trình Embedded C

🌱 GCC Commands trong Build Process chương trình Embedded C

    Khi bắt đầu học lập trình, các bạn thường chỉ tập trung vào phần code và chạy chương trình. Trong lập trình nói chung và lập trình Embedded nói riêng, việc hiểu quá trình Build Process cũng vô cùng quan trọng, mục đích là giúp dev hiểu rõ hơn về file/folder structure, cũng như phát hiện các lỗi trong quá trình compile.

    Bài viết đề cập đến các lệnh GCC Command để có thể hoàn thiện từng bước của quá trình Build Process một chương trình C, từ các file source code (.c/.h) đến các file binary, file thực thi (.exe).



Build Process trong C?

    Build Process là một quá trình xử lý với Input là các file source code (.c/.cpp/.h/.s/...) và đầu ra là các file nhị phân để xử dụng (.exe/.elf/.hex/.bin/...).

    ➤ Các bạn có thể tham khảo thêm bài viết về Build Process!

    Build Process trong một chương trình C sẽ trải qua các bước sau:

Build Process Multiple Files

    Quá trình trên đã được giải thích trong bài viết về Build Process và sẽ được giải thích từng bước theo GCC command dưới đây!

Trình biên dịch GCC

    GCC - GNU Compiler Collection là một tập hợp các trình biên dịch được thiết kế cho nhiều ngôn ngữ lập trình khác nhau. GCC là một thành phần quan trọng của GNU toolchain, và được hầu hết các hệ điều hành giống Unix, như Linux và Mac OS X chọn làm trình dịch tiêu chuẩn (Tham khảo Wiki).

    Nói chung GCC là trình biên dịch chúng ta cần sử dụng cho Step 2 ở trên - Compilation, biến các file source code thành các file Assembly - mã máy.

    Trên thực tế thì GCC có thể dùng để giải quyết tất cả công việc trên 😁

👉 Sử dụng GCC để xử lý Build Process như thế nào?

    Trước tiên máy của bạn cần có GCC trước. Nếu cài một số IDE như Codeblock, Dev C++ thì máy đã có sẵn GCC rồi. Còn không thì hãy thử search GCC download trên mạng nhé!

    Cách kiểm tra GCC + phiên bản trên máy, các bạn mở cửa sổ cmd lên và gõ lệnh sau:

D:\test\GCC>gcc --version
gcc (GCC) 12.4.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    ↪ OK! Sau khi đã có GCC thì ta sẽ bắt đầu từng Step như sơ đồ Build Process:

    Đầu tiên mình có một file source code: main.c.

// main.c

#include <stdio.h>

#define TEST_NUMBER (7U)

void main()
{
printf("Hello!, num=%d", TEST_NUMBER);
return;
}

    Cần cd đến folder chứa Project của mình hoặc trỏ đến dường dẫn của folder đó và gõ cmd để hiển thị của sổ Command Line.

👌 Step 1. Preprocessor

    Step này sẽ gộp các file source với file thư viện tương ứng (ở đây là stdio.h), cùng với đó là xử lý các chỉ thị tiền xử lý, ở đây là #define.

    Câu lệnh GCC cho Step này:

    gcc -E main.c -o main.i

    Output của Step này là Extended File - main.i như sau:

D:\test\GCC>gcc -E main.c -o main.i

D:\test\GCC>ls
main.c main.i

    File này rất nhiều nội dung, chủ yếu là nội dung của thư viện stdio.h. Cái chúng ta quan tâm là phần dưới cùng của file, phần tiền xử lý #define đã được thay thế.

    Dưới đây làm một phần của file main.i (phần đầu là nội dung file stdio.h khá dài):

// ... stdio.h file contents

static __inline int
_putchar_unlocked(int _c)
{
struct _reent *_ptr;

_ptr = (__getreent());
return (__sputc_r(_ptr, _c, ((_ptr)->_stdout)));
}
# 801 "/usr/include/stdio.h" 3 4

# 4 "main.c" 2


# 7 "main.c"
void main()
{
printf("Hello!, num=%d", (7U));
return;
}

👌 Step 2. Compilation

    Quá trình này sẽ biến file mai.i trên thành file mã máy - Assembly.

    Câu lệnh:

    gcc -S main.i -o main.s

    Output là file main.s như này, các bạn có kiến thức về ngôn ngữ Assembly thì có thể đọc hiểu được:

D:\test\GCC>gcc -S main.i -o main.s

D:\test\GCC>ls
main.c main.i main.s

    Nội dung Assembly file sẽ khác nhau do compile và cách compile cho từng dòng chip. Dưới đây là nội dung main.s khi compile trên Window:

.file	"main.c"
.text
.def __main; .scl 2; .type 32; .endef
.section .rdata,"dr"
.LC0:
.ascii "Hello!, num=%d\0"
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
movl $7, %edx
leaq .LC0(%rip), %rax
movq %rax, %rcx
call printf
nop
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 12.4.0"
.def printf; .scl 2; .type 32; .endef

👌 Step 3. Assembler

    Step này sử dụng trình Assembler thay thì Compiler, nó gộp các file .s vừa tạo với các file .s có sẵn (nếu có) tạo thành các file object.

    Câu lệnh:

    as main.s -o main.o

    Output là file main.o, với nội dung và định dạng mà chúng ta không đọc được đâu 😂

D:\test\GCC>as main.s -o main.o

D:\test\GCC>ls
main.c main.i main.o main.s

    File object này là binary rồi nên khi bạn mở định dạng text lên sẽ không đọc được nội dung.

👌 Step 4. Linking

    Sau khi có các file object, chúng sẽ được Link cùng với các static library (nếu có).

    Câu lệnh:

    gcc -v -o main main.o

    Output của quá trình này là file main.exe dùng để run. Bây giờ chỉ cần gõ main, hoặc main.exe + Enter là chương trình sẽ chạy ra kết quả.

    Các bước trên đây là các câu lệnh cơ bản nhất, các bạn có thể tìm hiểu thêm về Build Process và các Compiler option ở các bài viết sau!

>>>>>> Follow ngay <<<<<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊

1 Nhận xét

Mới hơn Cũ hơn
//
Avatar

Sign In

New User? Sign Up Now

or

By Signing In my Blog, you agree with: Privacy Policy & Cookie Policy.