這個(gè)匯編程序讀入一個(gè)字符串,并計(jì)算結(jié)果。支持加減乘除括號(hào),不支持浮點(diǎn)數(shù),不支持查錯(cuò)。以下是匯編以及注釋。匯編程序使用
這篇文章的程序編譯并執(zhí)行。
這個(gè)程序可以覆蓋除了浮點(diǎn)以外的幾乎所有參數(shù)格式,用于測(cè)試匯編器是否正確。
1 CONSTANT
2 INPUT stra:(11+22)*(33+44)
3 VARIABLE
4 RESULT int32
5 CODE
6
7 MOV EDI, int32 INPUT //將輸入的字符串指針?lè)湃隕DI
8 CALL @GETEXP //EAX=GETEXP
9 MOV int32 [RESULT], EAX //輸出結(jié)果
10 MOV EAX, int32 RESULT
11 RET
12
13 @GETEXP: //從EDI讀取一個(gè)表達(dá)式,結(jié)果放入EAX,偏移
14 PUSH EDX
15 CALL @GETTERM
16 @GETEXP_LOOP_BEGIN:
17 CMP int8 [EDI], int8 $+ //檢查操作符是否'+'
18 JE @GETEXP_ADD //是則跳往GETEXP_ADD
19 CMP int8 [EDI], int8 $- //檢查操作符是否'-'
20 JE @GETEXP_SUB //是則跳往GETEXP_SUB
21 @GETEXP_FINISHED: //否則直接退出
22 POP EDX
23 RET
24 @GETEXP_ADD:
25 INC EDI //跳過(guò)加號(hào)
26 MOV EDX, EAX //EDX=EAX
27 CALL @GETTERM //EAX=GETTERM
28 ADD EAX, EDX //EAX=EAX+EDX
29 JMP @GETEXP_LOOP_BEGIN //繼續(xù)循環(huán)
30 @GETEXP_SUB:
31 INC EDI //跳過(guò)減號(hào)
32 MOV EDX, EAX //EDX=EAX
33 CALL @GETTERM //EAX=GETTERM
34 SUB EDX, EAX //EDX=EDX-EAX
35 MOV EAX, EDX //EAX=EDX
36 JMP @GETEXP_LOOP_BEGIN //繼續(xù)循環(huán)
37
38 @GETTERM: //從EDI讀取一個(gè)只含有乘除法的字符串,結(jié)果放入EAX,偏移
39 PUSH EDX
40 PUSH EBX
41 CALL @GETFACTOR //讀取一個(gè)factor
42 @GETTERM_LOOP_BEGIN:
43 CMP int8 [EDI], int8 $* //檢查操作符是否'*'
44 JE @GETTERM_MULTIPLE //是則跳往GETTERM_MULTIPLE
45 CMP int8 [EDI], int8 $/ //檢查操作符是否'/'
46 JE @GETTERM_DIVID //是則跳往GETTERM_DIVID
47 @GETTERM_FINISHED: //否則直接退出
48 POP EBX
49 POP EDX
50 RET
51 @GETTERM_MULTIPLE:
52 INC EDI //跳過(guò)乘號(hào)
53 MOV EDX, EAX //EDX=EAX
54 CALL @GETFACTOR //EAX=GETFACTOR
55 IMUL EAX, EDX //EDX:EAX=EAX*EDX
56 JMP @GETTERM_LOOP_BEGIN //繼續(xù)循環(huán)
57 @GETTERM_DIVID:
58 INC EDI //跳過(guò)除號(hào)
59 MOV EBX, EAX //EBX=EAX
60 CALL @GETFACTOR //EAX=GETFACTOR
61 XCHG EAX, EBX //交換EAX和EBX,EAX是被除數(shù),EBX是除數(shù)
62 XOR EDX, EDX //EDX=0
63 IDIV EBX //EAX=EDX:EAX/EBX
64 JMP @GETTERM_LOOP_BEGIN //繼續(xù)循環(huán)
65
66 @GETFACTOR: //從EDI讀取一個(gè)數(shù)字或被括號(hào)包圍的字符串,結(jié)果放入EAX,偏移EDI
67 CMP int8 [EDI], int8 $( //檢查第一個(gè)字符是否'('
68 JE @GETFACTOR_BRACKED //是則跳往GETFACTOR_BRACKED
69 JMP @CONVERT //否則直接使用CONVERT代替
70 @GETFACTOR_BRACKED:
71 INC EDI //跳過(guò)括號(hào)
72 CALL @GETEXP //調(diào)用GETEXP計(jì)算一個(gè)表達(dá)式
73 INC EDI //跳過(guò)右括號(hào)
74 RET //退出
75
76 @CONVERT: //同UNSIGNED_CONVERT,支持負(fù)號(hào)
77 CMP int8 [EDI], int8 $- //檢查第一個(gè)符號(hào)是不是負(fù)號(hào)
78 JE @CONVERT_NEGATIVE //是則跳往CONVERT_NEGATIVE處理負(fù)號(hào)
79 CALL @UNSIGNED_CONVERT //否則調(diào)用UNSIGNED_CONVERT
80 RET //退出
81 @CONVERT_NEGATIVE:
82 INC EDI //略過(guò)負(fù)號(hào)
83 CALL @UNSIGNED_CONVERT //調(diào)用UNSIGNED_CONVERT
84 NEG EAX //將EAX變負(fù)
85 RET //退出
86
87 @UNSIGNED_CONVERT: //將EDI指向的字符串轉(zhuǎn)成整數(shù),放入EAX,并偏移EDI至末尾
88 XOR EAX, EAX
89 PUSH EDX
90 @UNSIGNED_CONVERT_LOOP_BEGIN:
91 CMP int8 [EDI], int8 $0 //檢查字符是否大于等于'0'
92 JB @UNSIGNED_CONVERT_LOOP_END //失敗則退出
93 CMP int8 [EDI], int8 $9 //檢查字符是否小于等于'9'
94 JA @UNSIGNED_CONVERT_LOOP_END //失敗則退出
95 MOV EDX, int32 10 //EDX=10
96 MUL EDX //EDX:EAX = EAX*EDX
97 XOR EDX, EDX //EDX=0
98 MOV DL, int8 [EDI] //DL=*EDI
99 SUB EDX, int32 $0 //EDX-='0'
100 ADD EAX, EDX //EAX=EAX+EDX
101 INC EDI //EDI++
102 JMP @UNSIGNED_CONVERT_LOOP_BEGIN //再次執(zhí)行循環(huán)
103 @UNSIGNED_CONVERT_LOOP_END:
104 POP EDX
105 RET
posted on 2009-02-26 09:05
陳梓瀚(vczh) 閱讀(2213)
評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi):
JIT