Skip to content
ccckmit edited this page Jan 18, 2019 · 2 revisions

c0c 編譯器

c0c 編譯器是 C0 語言的編譯器。

C0 語言是 C 語言的簡化版!

c0c 可以將 C0 語言編譯成 x86 的 GNU 組合語言,您可以再用 gcc 將該組合語言組譯後執行,其使用方法如下:

PS D:\ccc\book\c0c\c0c> make
gcc -O0 -std=gnu99 -Wall -Werror c0c.c compiler.c lexer.c map.c scan.c strTable.c util.c vm.c x86.c -o c0c
PS D:\ccc\book\c0c\c0c> cd ..
PS D:\ccc\book\c0c> cd test
PS D:\ccc\book\c0c\test> ../c0c/c0c sum
#include <stdio.h>

int sum(int n) {
  int s = 0;
  int i = 1;
  printf("i=%d s=%d n=%d\n", i, s, n);
  while (i <= n) {
    s = s + i;
    printf("i=%d s=%d\n", i, s);
    i = i + 1;
  }
  return s;
}

int main() {
  int total = sum(10);
  printf("sum(10)=%d\n", total);
}

================= lex =================
0001:#          line=1 pos=1 type=Char
0002:include    line=1 pos=8 type=Id
0003:<          line=1 pos=10 type=Char
0004:stdio      line=1 pos=15 type=Id
0005:.          line=1 pos=16 type=Char
0006:h          line=1 pos=17 type=Id
0007:>          line=1 pos=18 type=Char
0008:int        line=3 pos=3 type=Type
0009:sum        line=3 pos=7 type=Id
0010:(          line=3 pos=8 type=Char
0011:int        line=3 pos=11 type=Type
0012:n          line=3 pos=13 type=Id
0013:)          line=3 pos=14 type=Char
0014:{          line=3 pos=16 type=Char
0015:int        line=4 pos=5 type=Type
0016:s          line=4 pos=7 type=Id
0017:=          line=4 pos=9 type=Char
0018:0          line=4 pos=11 type=Number
0019:;          line=4 pos=12 type=Char
0020:int        line=5 pos=5 type=Type
0021:i          line=5 pos=7 type=Id
0022:=          line=5 pos=9 type=Char
0023:1          line=5 pos=11 type=Number
0024:;          line=5 pos=12 type=Char
0025:printf     line=6 pos=8 type=Id
0026:(          line=6 pos=9 type=Char
0027:"i=%d s=%d n=%d\n" line=6 pos=27 type=Literal
0028:,          line=6 pos=28 type=Char
0029:i          line=6 pos=30 type=Id
0030:,          line=6 pos=31 type=Char
0031:s          line=6 pos=33 type=Id
0032:,          line=6 pos=34 type=Char
0033:n          line=6 pos=36 type=Id
0034:)          line=6 pos=37 type=Char
0035:;          line=6 pos=38 type=Char
0036:while      line=7 pos=7 type=Id
0037:(          line=7 pos=9 type=Char
0038:i          line=7 pos=10 type=Id
0039:<=         line=7 pos=13 type=Char
0040:n          line=7 pos=15 type=Id
0041:)          line=7 pos=16 type=Char
0042:{          line=7 pos=18 type=Char
0043:s          line=8 pos=5 type=Id
0044:=          line=8 pos=7 type=Char
0045:s          line=8 pos=9 type=Id
0046:+          line=8 pos=11 type=Char
0047:i          line=8 pos=13 type=Id
0048:;          line=8 pos=14 type=Char
0049:printf     line=9 pos=10 type=Id
0050:(          line=9 pos=11 type=Char
0051:"i=%d s=%d\n" line=9 pos=24 type=Literal
0052:,          line=9 pos=25 type=Char
0053:i          line=9 pos=27 type=Id
0054:,          line=9 pos=28 type=Char
0055:s          line=9 pos=30 type=Id
0056:)          line=9 pos=31 type=Char
0057:;          line=9 pos=32 type=Char
0058:i          line=10 pos=5 type=Id
0059:=          line=10 pos=7 type=Char
0060:i          line=10 pos=9 type=Id
0061:+          line=10 pos=11 type=Char
0062:1          line=10 pos=13 type=Number
0063:;          line=10 pos=14 type=Char
0064:}          line=11 pos=3 type=Char
0065:return     line=12 pos=8 type=Id
0066:s          line=12 pos=10 type=Id
0067:;          line=12 pos=11 type=Char
0068:}          line=13 pos=1 type=Char
0069:int        line=15 pos=3 type=Type
0070:main       line=15 pos=8 type=Id
0071:(          line=15 pos=9 type=Char
0072:)          line=15 pos=10 type=Char
0073:{          line=15 pos=12 type=Char
0074:int        line=16 pos=5 type=Type
0075:total      line=16 pos=11 type=Id
0076:=          line=16 pos=13 type=Char
0077:sum        line=16 pos=17 type=Id
0078:(          line=16 pos=18 type=Char
0079:10         line=16 pos=20 type=Number
0080:)          line=16 pos=21 type=Char
0081:;          line=16 pos=22 type=Char
0082:printf     line=17 pos=8 type=Id
0083:(          line=17 pos=9 type=Char
0084:"sum(10)=%d\n" line=17 pos=23 type=Literal
0085:,          line=17 pos=24 type=Char
0086:total      line=17 pos=30 type=Id
0087:)          line=17 pos=31 type=Char
0088:;          line=17 pos=32 type=Char
0089:}          line=18 pos=1 type=Char
============ compile =============
=============vmToAsm()==============
# extern   printf                     # printf                     #
# file     "sum.c"                    # "sum.c"                    #
# str      _Str0    "i=%d s=%d n=%d\n"          # _Str0    "i=%d s=%d n=%d\n"          #
# str      _Str3    "i=%d s=%d\n"          # _Str3    "i=%d s=%d\n"          #
# str      _Str4    "sum(10)=%d\n"          # _Str4    "sum(10)=%d\n"          #
# function sum      int               # sum      int               # 6
# param    n        int               # n        int               # P0
# local    s        int               # s        int               # L0
# =        s        0                 # L0       0                 #
# local    i        int               # i        int               # L1
# =        i        1                 # L1       1                 #
# arg      _Str0                      # $_Str0                     # 0
# arg      i                          # L1                         # 1
# arg      s                          # L0                         # 2
# arg      n                          # P0                         # 3
# local    t0                         # t0                         # L2
# call     t0       printf            # L2       _printf           #
# label    _WBEGIN1                   # _WBEGIN1                   #
# <=       t0       i        n        # L2       L1       P0       #
# jz       _WEND2   t0                # _WEND2   L2                #
# +        t0       s        i        # L2       L0       L1       #
# =        s        t0                # L0       L2                #
# arg      _Str3                      # $_Str3                     # 0
# arg      i                          # L1                         # 1
# arg      s                          # L0                         # 2
# call     t0       printf            # L2       _printf           #
# +        t0       i        1        # L2       L1       1        #
# =        i        t0                # L1       L2                #
# jmp      _WBEGIN1                   # _WBEGIN1                   #
# label    _WEND2                     # _WEND2                     #
# return   s                          # L0                         #
# -function sum                        # sum                        #
# function main     int               # main     int               # 4
# local    total    int               # total    int               # L0
# arg      10                         # 10                         # 0
# local    t0                         # t0                         # L1
# call     t0       sum               # L1       _sum              #
# =        total    t0                # L0       L1                #
# arg      _Str4                      # $_Str4                     # 0
# arg      total                      # L0                         # 1
# call     t0       printf            # L1       _printf           #
# -function main                       # main                       #
# -file    "sum.c"                    # "sum.c"                    #

然後會輸出組合語言檔 sum0.s 如下

# extern   printf                     # printf                     #         
# file     "sum.c"                    # "sum.c"                    #         
	.file "sum.c"
	.def	___main;	.scl	2;	.type	32;	.endef
# str      _Str0    "i=%d s=%d n=%d\n"          # _Str0    "i=%d s=%d n=%d\n"          #         
	.section .rdata,"dr"
_Str0:
	.ascii "i=%d s=%d n=%d\n\0"
	.text
# str      _Str3    "i=%d s=%d\n"          # _Str3    "i=%d s=%d\n"          #         
	.section .rdata,"dr"
_Str3:
	.ascii "i=%d s=%d\n\0"
	.text
# str      _Str4    "sum(10)=%d\n"          # _Str4    "sum(10)=%d\n"          #         
	.section .rdata,"dr"
_Str4:
	.ascii "sum(10)=%d\n\0"
	.text
# function sum      int               # sum      int               # 6       
	.text
	.globl	_sum
	.def	sum;	.scl	2;	.type	32;	.endef
_sum:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
# param    n        int               # n        int               # P0      
# local    s        int               # s        int               # L0      
# =        s        0                 # L0       0                 #         
	movl	$0, %ebx
	movl	%ebx, -4(%ebp)
# local    i        int               # i        int               # L1      
# =        i        1                 # L1       1                 #         
	movl	$1, %ebx
	movl	%ebx, -8(%ebp)
# arg      _Str0                      # $_Str0                     # 0       
	movl $_Str0, %eax
	movl %eax, 0(%esp)
# arg      i                          # L1                         # 1       
	movl -8(%ebp), %eax
	movl %eax, 4(%esp)
# arg      s                          # L0                         # 2       
	movl -4(%ebp), %eax
	movl %eax, 8(%esp)
# arg      n                          # P0                         # 3       
	movl 8(%ebp), %eax
	movl %eax, 12(%esp)
# local    t0                         # t0                         # L2      
# call     t0       printf            # L2       _printf           #         
	call _printf
	movl %eax, -12(%ebp)
# label    _WBEGIN1                   # _WBEGIN1                   #         
_WBEGIN1:
# <=       t0       i        n        # L2       L1       P0       #         
	movl -8(%ebp), %eax
	movl 8(%ebp), %ebx
	cmpl %ebx, %eax
	setle %al
	movsbl	%al, %eax
	movl	%eax, -12(%ebp)
# jz       _WEND2   t0                # _WEND2   L2                #         
	movl	-12(%ebp), %eax
	cmpl	$0, %eax
	je	_WEND2
# +        t0       s        i        # L2       L0       L1       #         
	movl	-4(%ebp), %eax
	addl	-8(%ebp), %eax
	movl	%eax, -12(%ebp)
# =        s        t0                # L0       L2                #         
	movl	-12(%ebp), %ebx
	movl	%ebx, -4(%ebp)
# arg      _Str3                      # $_Str3                     # 0       
	movl $_Str3, %eax
	movl %eax, 0(%esp)
# arg      i                          # L1                         # 1       
	movl -8(%ebp), %eax
	movl %eax, 4(%esp)
# arg      s                          # L0                         # 2       
	movl -4(%ebp), %eax
	movl %eax, 8(%esp)
# call     t0       printf            # L2       _printf           #         
	call _printf
	movl %eax, -12(%ebp)
# +        t0       i        1        # L2       L1       1        #         
	movl	-8(%ebp), %eax
	addl	$1, %eax
	movl	%eax, -12(%ebp)
# =        i        t0                # L1       L2                #         
	movl	-12(%ebp), %ebx
	movl	%ebx, -8(%ebp)
# jmp      _WBEGIN1                   # _WBEGIN1                   #         
	jmp	_WBEGIN1
# label    _WEND2                     # _WEND2                     #         
_WEND2:
# return   s                          # L0                         #         
	movl -4(%ebp), %eax
	leave
	ret
# -function sum                        # sum                        #         
	movl $0, %eax
	leave
	ret
# function main     int               # main     int               # 4       
	.text
	.globl	_main
	.def	main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$16, %esp
	call	___main
# local    total    int               # total    int               # L0      
# arg      10                         # 10                         # 0       
	movl $10, %eax
	movl %eax, 0(%esp)
# local    t0                         # t0                         # L1      
# call     t0       sum               # L1       _sum              #         
	call _sum
	movl %eax, -8(%ebp)
# =        total    t0                # L0       L1                #         
	movl	-8(%ebp), %ebx
	movl	%ebx, -4(%ebp)
# arg      _Str4                      # $_Str4                     # 0       
	movl $_Str4, %eax
	movl %eax, 0(%esp)
# arg      total                      # L0                         # 1       
	movl -4(%ebp), %eax
	movl %eax, 4(%esp)
# call     t0       printf            # L1       _printf           #         
	call _printf
	movl %eax, -8(%ebp)
# -function main                       # main                       #         
	movl $0, %eax
	leave
	ret
# -file    "sum.c"                    # "sum.c"                    #         
	.ident	"c0c: 0.0.1"
	.def	_puts;	.scl	2;	.type	32;	.endef

Clone this wiki locally