这是我使用MASM从输入文件中简单计算内容的任务。我们使用的书是“x86处理器的汇编语言”。
现在我正在尝试使用中缀进行后缀转换。我尝试转换的输入是:12/3+4
,但它刚刚停止并显示.exe已停止工作,我发现它停在主函数的INVOKE CheckAddSub
处。
你能帮我看看那个过程中出了什么问题吗?我曾尝试使用stack来推送/弹出但后来我改为使用,因为我正在调用函数,我认为不使用堆栈会更容易。非常感谢您花时间查看我的代码。
INCLUDE C:\Irvine\Irvine32.inc
INCLUDE C:\Irvine\macros.inc
CheckAddSub PROTO, seStr1:PTR BYTE, outStr1:PTR BYTE, pCo:DWORD, pDo:DWORD,
outCo1:DWORD
CheckMulDiv PROTO, seStr2:PTR BYTE, outStr2:PTR BYTE, theCo:DWORD,
theDo:DWORD, outCo2:DWORD
.data
inputStr BYTE 20 dup(?) ;input array
outputStr BYTE 20 dup(?) ;postfix array
sizeSt DWORD 20
secStr BYTE 10 dup(?) ;to store the operator
count DWORD 0
dStr BYTE 0
outCount DWORD 0
.code
main PROC
mWrite "Input: "
mov edx, OFFSET inputStr
mov ecx, SIZEOF inputStr - 1
call ReadString
mov esi, OFFSET inputStr ;now the input str has elements
mov edi, OFFSET outputStr ;for storing the postfix
mov ecx, sizeSt ;to loop
mov edx, OFFSET secStr ;to store operator
L1:
mov ebx, [esi]
.if bl=='+'|| bl=='-'
inc count
.if count > 1 ;when count is 2 mean there is already element in
the secStr array so i can do the checking
INVOKE CheckAddSub, ADDR secStr, ADDR outputStr, count, dStr,outCount
inc dStr ;dStr is to store the index number of the secStr
array, after the zero index predencency is checked,
;increment dStr to indicate the index number this
current operator in secStr array
.endif
mov [edx],ebx ;put the operator into secStr
add edx,1
.elseif bl=='*'|| bl =='/'
inc count
.if count > 1
INVOKE CheckMulDiv, ADDR secStr, ADDR outputStr , count, dStr, outCount
inc dStr
.endif
mov [edx],ebx
add edx,1
.else ;when it is operand(number), put into output array
mov [edi], ebx
inc outCount
.endif
inc edi
inc esi
dec ecx
cmp ecx,0
jne L1
mov edx, OFFSET outputStr
mWrite "the postfix string is: "
call WriteString
INVOKE ExitProcess,0
main ENDP
;-----------------------------------------------------------
CheckAddSub PROC USES edx edi eax ecx ebx,
seStr1:PTR BYTE, ;secStr
outStr1:PTR BYTE, ;outputStr
pCo:DWORD,
pDo:DWORD,
outCo1:DWORD
;------------------------------------------------------------
mov edx, seStr1
mov edi, outStr1
LW:
mov ebx, [edx+pDo] ;edx+pDo is the last element in the array,
like stack the top element
.if bl=='+'|| bl=='-'|| bl=='*' || bl=='/'
mov [edi+outCo1],ebx ;if one of these operator exists in the
secStr array, then put this operator into
the outputStr array
mov [edx+pDo], 0 ;put null in this current index,indicating
this element is already pop out from the
secStr array
inc outCo1
.endif
.if pDo!=0
sub pDo,1
.endif
dec pCo
cmp pCo,1
jne LW
je L5
L5: ret
CheckAddSub ENDP
;------------------------------------------------------
CheckMulDiv PROC USES edx edi eax ecx ebx,
seStr2:PTR BYTE,
outStr2:PTR BYTE,
theCo:DWORD,
theDo:DWORD,
outCo2:DWORD
;-------------------------------------------------------
mov edx, seStr2
mov edi, outStr2
LR:
mov ebx,[edx+theDo]
.if bl=='*'|| bl=='/'
mov [edi+outCo2],ebx
mov [edx+theDo],0
inc outCo2
.endif
.if theDo!=0
sub theDo,1
.endif
dec theCo
cmp theCo, 1
jne LR
je L6
L6: ret
CheckMulDiv ENDP
END main
答案 0 :(得分:2)
call ReadString mov esi, OFFSET inputStr ;now the input str has elements mov edi, OFFSET outputStr ;for storing the postfix mov ecx, sizeSt ;to loop
您正在使用固定数量的迭代。在这种情况下,20,因为 sizeSt 是这样定义的。
你想要的是迭代你实际收到的字节。您从 ReadString 中获得了EAX
的计数,因此请使用它:
call ReadString
mov esi, OFFSET inputStr ;now the input str has elements
mov edi, OFFSET outputStr ;for storing the postfix
mov ecx, eax ;to loop
mov ebx, [esi] ... mov [edx], ebx ... mov [edi], ebx
由于您正在处理字节,因此必须使用字节大小的BL
寄存器而不是DWORD大小的EBX
寄存器!
dStr BYTE 0
考虑PROTO
/ INVOKE
,您需要将其更改为:
dStr DWORD 0