Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何以及在哪里结束这个有限状态机程序的工作?_Assembly_X86_Masm_Irvine32_State Diagram - Fatal编程技术网

Assembly 如何以及在哪里结束这个有限状态机程序的工作?

Assembly 如何以及在哪里结束这个有限状态机程序的工作?,assembly,x86,masm,irvine32,state-diagram,Assembly,X86,Masm,Irvine32,State Diagram,我根据给我的图表写了这个程序。我只是不知道在哪里,如何阻止它运行。它永远都在要求投入。在我的程序中的何处添加退出命令?有什么想法吗 多谢各位 INCLUDE Irvine32.inc .data A DWord ? B dword ? prompta byte "what is your digit a?",0 promptb byte "what is your digit b?",0 message0 byte "you are in s0 with output ",0 message

我根据给我的图表写了这个程序。我只是不知道在哪里,如何阻止它运行。它永远都在要求投入。在我的程序中的何处添加退出命令?有什么想法吗

多谢各位

INCLUDE Irvine32.inc
.data
A DWord ?
B dword ?
prompta  byte "what is your digit a?",0
promptb  byte "what is your digit b?",0
message0 byte "you are in s0 with output ",0
message1 byte "you are in s1 with output ",0
message2 byte "you are in s2 with output ",0
message3 byte "you are in s3 with output ",0
.code

 main PROC


  call s0
   call waitmsg
初始状态为S0

 myexit proc
   mov eax, white+16*black
   call settextcolor
   call waitmsg
   ret
 myexit endp
这里的退出程序不起作用

 readdigits proc
 mov edx, offset prompta
 call writestring
 call readint   ; dword into eax
 mov a,eax
 mov edx, offset promptb
 call writestring
 call readint
 mov b,eax

 ret 
 readdigits endp
S0、S1、S2、S3的程序从这里开始

 s0 proc
 mov edx,offset message0
 call writestring
 mov eax,0               ;Output is 0 in State 0

 call writedec
 call crlf

 call readdigits

.if(a==0)&&(b==0) 
 call s0
.endif
.if(a==1)&&(b==1)
 call s1
.endif
call s2
ret
s0 endp

s1 proc
mov edx,offset message1
call writestring
mov eax,0               ;Output is 1 in State 0
call writedec
call crlf

 call readdigits
.if(a==0)&&(b==0) 
 call s2
.endif
.if(a==1)&&(b==1)
 call s3
.endif
 call s1
 ret
 s1 endp

 s2 proc
 mov edx,offset message2
 call writestring
 mov eax,1                  ;Output is 1 in State 2
 call writedec
 call crlf

 call readdigits
.if(a==0)&&(b==0) 
 call s0
.endif
.if(a==1)&&(b==1)
 call s1
.endif
call s2
ret
s2 endp


s3 proc
mov edx,offset message3
call writestring
mov eax,1                 ;Output is 1 in State 2
call writedec
call crlf

call readdigits
.if(a==0)&&(b==0) 
 call s2
.endif
.if(a==1)&&(b==1)
call s0
.endif
call s1
ret
s3 endp


main endp
end main

通常,对于状态机,您可以将其作为单个函数编写,使用
jmp
而不是
call
转到下一个状态。

您的状态函数永远不会返回,它们总是跳转到新状态(或重新运行当前状态,如
s1
底部的
调用s1
),最后的
ret
永远不会到达,因此,您只是在推送越来越多的返回地址,阻止您实际返回到
main

使用像
s1:
这样的标签,而不是
s1 proc
。或者您仍然可以使用MASM语法来假装每个函数都是单独的函数,但是使用
JMPS2
来跟踪调用下一个状态

然后当您检测到终止条件作为下一个状态时,您可以
ret
,它将返回到
main


这有一个很大的优势,即您可以使用条件分支,如
jne s1
,而不是跳过调用/jmp
。MASM的
.if
语法可能不足以为您做到这一点,但无论如何,您都会因为使用它而错过大量优化。e、 g.
a==0&&b==0
可通过
mov-eax,a
/
或eax,b
/
jz检查,两者均为零
。另外,只有2个“变量”,将它们保存在调用保留寄存器中,如
ebx
esi
或其他什么,而不是将它们保存在内存中。这就是寄存器的用途!你在用asm写东西

此外,您还可以通过布局进行优化,使
s3
可以归入
s1
,而不是以
jmp s1
结尾。或者保持简单并保持
jmp
。(如果我在做这个优化,我会把
jmps1
作为注释,作为文档,作为下一个状态是有意的。)


剩下的代码嵌套在
主进程中
,这很奇怪
,但可能不会造成实际问题。但是以
main
开头的第一个代码块显示它从
callwaitmsg
进入
myexit proc
?这太奇怪了,但如果
myexit
是您希望发生的事情,那么它实际上应该会起作用


另外,直到文件末尾,您才有一行
main endp
,因此您告诉汇编程序,其他
proc
声明在
main

中(可能与主题无关)。您将剩下的代码嵌套在
main
过程中?所以它从
callwaitmsg
进入
myexit proc
?这太奇怪了,直到文件的末尾才有
main endp
行。我认为这并不能解决您的问题,因为我认为您说的是
S0
永不返回。您开始使用的图表是否有结束状态?(可以绘制为双圆。)@prl否,图表没有结束状态。