我在 TASM 中有这个 RPN 计算器程序,可以计算字符串 data_stack 中的表达式:
.model small
.stack 100h
.data
data_stack db '3 4 +', 0
top equ 0
result db 0
.code
start:
mov ax, @data
mov ds, ax
mov bx, offset data_stack
mov cl, 1
read_argument:
mov dx, [bx]
cmp dx, 0
je calculate_result
push dx
inc cl
inc bx
jmp read_argument
calculate_result:
jmp calculate_expression
calculate_expression:
pop bx
mov al, [bx]
cmp al, '+'
je add_operands
cmp al, '-'
je subtract_operands
add_operands:
pop bx
add al, [bx]
jmp calculate_expression
subtract_operands:
pop bx
sub al, [bx]
jmp calculate_expression
print_result:
mov ah, 02h
mov dl, al
int 21h
exit_program:
mov ah, 4Ch
int 21h
end start
但是它在调试模式下崩溃了:
mov bx, offset data_stack
我在Dosbox工作,我不知道原因,所以我应该使用另一个寄存器还是什么。
我测试了一些 rpn 字符串,调试器显示了良好的结果。 它适用于数字
1 - 9
,结果应在 -128,255
范围内。
字符串中的每个字符均以空格 (20h) 分隔。
我还在 cl 寄存器中添加了 flag
只是为了确保堆栈包含 2 个值。
https://www-stone.ch.cam.ac.uk/documentation/rrf/rpn.html
.model small
.stack 100h
.data
data_stack db '9 9 + 9 9 * - 8 8 * - 1 -',0
; strings tested
; 3 + 4
; '3 4 + ', 0
; 5 * 3 + 9/3 + 9
; '5 3 * 9 3 / + 9 + ',0
; 9 * 2 * 5 + 7 + 8 * 5
; '9 2 * 5 * 7 + 8 5 * +',0
; 9 - 5 * 3 + 7 * 7 + 3 - 8 * 9
; '9 5 3 * - 7 7 * + 3 + 8 9 * -',0
; 9 + 9 - 9 * 9 - 8 * 8 - 1
; '9 9 + 9 9 * - 8 8 * - 1 -',0
add_zero db 0
save_bx dw ?
result db 0
.code
start:
mov ax, @data
mov ds, ax
mov bx, offset data_stack
sub bx,2
mov cl, 0 ; flag, if digits are on the stack
; 0 = no values available, no operation
; 1 = 1 value is on the stack, no operation
; 2+ = more than 2 values are on the stack, operation allowed
xor dx,dx
read_argument:
add bx,2
mov dl, [bx] ; ASCII code for '1' - '9' = 31h - 39h
; '*' = 2ah
; '/' = 2fh
; '+' = 2bh
; '-' = 2dh
cmp dl,0 ; end of string
jz print_result
check_sign:
cmp dl, 2fh
ja check_1
check_values_on_stack:
cmp cl, 2 ; 2 values are on the stack, so we can do arithmetic operation
jae arithmetic_operation
jmp no_operation
check_1:
cmp dx, 31h ; ok if >= 1
jb check_next_value
check_9:
cmp dx, 39h ; ok if <= 9
ja check_next_value
inc cl
value_ok:
sub dl,30h ; we want digits 1 - 9 not ASCII values of '1' - '9'
push dx ; save digit on stack
jmp check_next_value
no_operation:
xor cl,cl ; reset flag
check_next_value:
jmp read_argument
arithmetic_operation:
mov [save_bx], bx ; save address of element in string
pop bx ; pop digits
pop ax
cmp dl,2ah ; mul
jz mul_op
cmp dl,2fh ; div
jz div_op
cmp dl,2bh ; add
jz add_op
cmp dl,2dh ; sub
jz sub_op
mul_op:
mul bl
push ax
dec cl ; after operation one value is on the stack
jmp restore_bx
div_op:
div bl
push ax
dec cl ; after operation one value is on the stack
jmp restore_bx
add_op:
add al,bl
push ax
dec cl ; after operation one value is on the stack
jmp restore_bx
sub_op:
sub al,bl
push ax
dec cl ; after operation one value is on the stack
;jmp restore_bx
restore_bx:
mov bx, [save_bx] ; save address of element in string
mov [result],al
jmp check_next_value
print_result:
mov ah, 02h
mov dl, [result] ; show ASCII char equal to result
int 21h
exit_program:
mov ah, 4Ch
int 21h
end start