📄 nibolan.s
字号:
;数字2代表'+'和'-'操作符,数字3代表'*'和'/'操作符。数字5代表操作的数据。在转化逆波兰时用标识数字比较他们的优先级,在
;逆波兰表达式的计算时用标识数字判断数字和操作数。结果在r4寄存器中显示。
AREA StrCopy, CODE, READONLY
ENTRY
start
LDR r0, =string
BL math_function
stop
MOV r0, #0x18
LDR r1, =0x20026
SWI 0x123456
;/ 本代码段的作用是:将字符串数字,转化为数字型.
math_function
ldr r13,=stack
stmia r13!,{r4-r12}
ldr r5,=data_fix_simple
mov r7,#1
mov r4,#0x28 ;
stmia r5!,{r7}
stmia r5!,{r4}
loop_compare
ldrb r4,[r0]
cmp r4,#0 ;判断是否结束
beq next_deal_with ;是结束跳到next_deal_with处理
cmp r4,#0x28 ;比较是否是'('
moveq r7,#1
beq deal_with_simple
cmp r4,#0x2b ;判断是否是字符'-'
moveq r7,#2 ;是、标识为2
beq deal_with_simple
cmp r4,#0x2d ;判断是否是字符'+'
moveq r7,#2 ;是、标识为2
beq deal_with_simple
cmp r4,#0x2a ;判断是否是字符'*'
moveq r7,#3 ;是、标识为3
beq deal_with_simple
cmp r4,#0x2f ;判断是否是'/'
moveq r7,#3 ;是、标识为3
beq deal_with_simple
cmp r4,#0x29 ;判断是否是')'
moveq r7,#4 ;是、标识为4
beq deal_with_simple
mov r8,#0 ;接下来是数字字符的处理过程
mov r9,#10
sub r4,r4,#0x30
mul r8,r10,r9
mov r10,r8
add r10,r10,r4
mov r12,#5 ;是数字表示为5
mov r11,#2
add r0,r0,#1
b loop_compare
deal_with_simple cmp r11,#2 ;比较是否等于2,等于2说明经过了一次的数字处理
stmeqia r5!,{r12} ;将标识符5压入栈
stmeqia r5!,{r10} ;将上次数字处理的结果压入栈
moveq r11,#0 ;将r11标志清零
stmia r5!,{r7} ;将标识符压入栈内
stmia r5!,{r4} ;将非数字字符压栈
mov r10,#0 ;将r10清零
add r0,r0,#1 ;将r0指向下一个字符
b loop_compare ;跳转循环比较
next_deal_with cmpeq r11,#2
stmeqia r5!,{r12}
stmeqia r5!,{r10}
mov r7,#4
mov r4,#0x29
stmia r5!,{r7}
stmia r5!,{r4}
ldr r6,=data_fix_simple
ldr r5,=stack_data
ldr r7,=stack_simple
loop_judge ldr r1,[r6],#4 ;/本代码实现中缀表达式转化为逆波兰表达式。
cmp r1,#0 ;判断是否转化结束
beq calculate
cmpne r1,#5 ;判断书否是数据
bne first_judge ;跳转first_judge
stmia r5!,{r1} ;将数据的标识压入r5指向的数据栈
ldr r9,[r6]
stmia r5!,{r9} ;将数据压入数据栈
add r6,r6,#4 ;指向下一个标识
b loop_judge
first_judge cmp r1,#1
bne second_judge
stmia r7!,{r1}
ldr r9,[r6]
stmia r7!,{r9}
add r6,r6,#4
b loop_judge
second_judge cmp r1,#4
bne third_judge
loop0 ldr r9,[r7,#-8]
cmp r9,#1
subeq r7,r7,#8
addeq r6,r6,#4
beq loop_judge
stmneia r5!,{r9}
ldrne r10,[r7,#-4]
stmneia r5!,{r10}
subne r7,r7,#8
bne loop0
third_judge ldr r10,[r7,#-8]
cmp r1,r10
bls branch_third_judge
stmia r7!,{r1}
ldr r9,[r6]
stmia r7!,{r9}
add r6,r6,#4
b loop_judge
branch_third_judge
stmia r5!,{r10}
ldr r9,[r7,#-4]
stmia r5!,{r9}
sub r7,r7,#8
stmia r7!,{r1}
ldrls r11,[r6]
stmia r7!,{r11}
add r6,r6,#4
b loop_judge ;\继续循环执行
calculate ldr r5,=stack_data ;/本段代码的作用是:计算逆波兰表达式的值
ldr r6,=stack_simple
loop_calculate ldr r7,[r5],#4 ;取标识符
ldr r8,[r5] ;取标志符对应的数字、操作符、左括号或右括号
cmp r7,#5 ;判断是否是数据
stmeqia r6!,{r8} ;数据压入数据栈
addeq r5,r5,#4 ;数据的标识符
beq loop_calculate
cmp r7,#2 ;判断是否是加减操作符
beq excute_add_sub
cmp r7,#3 ;判断是否是乘除操作符
beq excute_mul_div
cmp r7,#0 ;判断是否结束
beq exit ;是则退出
excute_add_sub ldr r9,[r6,#-4]! ;/本代码实现加减运算
ldr r10,[r6,#-4]!
cmp r8,#43 ;判断是否为加法操作
addeq r10,r10,r9
stmeqia r6!,{r10} ;
addeq r5,r5,#4
beq loop_calculate
cmp r8,#45 ;判断是否是减法操作
subeq r10,r10,r9
stmeqia r6!,{r10}
addeq r5,r5,#4
beq loop_calculate ;\继续循环执行
excute_mul_div ldr r9,[r6,#-4]! ;/本代码实现乘除发运算
ldr r10,[r6,#-4]!
cmp r8,#0x2a
muleq r11,r9,r10
moveq r10,r11
stmeqia r6!,{r10}
addeq r5,r5,#4
beq loop_calculate
cmp r8,#0x2f
beq excute_div
excute_div mov r8,#0
loop sub r10,r10,r9
add r8,r8,#1
cmp r10,r9
bge loop
stmia r6!,{r8}
add r5,r5,#4
b loop_calculate ;\继续循环执行
exit ldr r4,[r6,#-4]
mov pc,r14
AREA ldrb_my, DATA, READWRITE
string DCB "(5+55)*(10/5-1)",0
safe_room0 dcd 0
data_fix_simple space 224
safe_room1 dcd 0
stack_data space 224
safe_room2 dcd 0
stack_simple space 224
stack space 32
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -