-
Notifications
You must be signed in to change notification settings - Fork 1
Home
ccckmit edited this page Jan 18, 2019
·
2 revisions
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