Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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 Can';不知道如何在汇编中正确实现while循环?_Assembly_X86_Masm - Fatal编程技术网

Assembly Can';不知道如何在汇编中正确实现while循环?

Assembly Can';不知道如何在汇编中正确实现while循环?,assembly,x86,masm,Assembly,X86,Masm,我正在尝试在程序集中实现以下伪代码: 我的解决方案尝试使用循环指令实现while循环,但这给了我一个无限循环。(我知道这是ECX中垃圾值的b/c,但我不知道如何克服这个问题并正确实现WHILE循环)。这是我的密码: .386 .model flat, stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD .data A WORD 9 B WORD 8 X WORD 15 sum WORD 0 .code main PROC L1:

我正在尝试在程序集中实现以下伪代码:

我的解决方案尝试使用循环指令实现while循环,但这给了我一个无限循环。(我知道这是ECX中垃圾值的b/c,但我不知道如何克服这个问题并正确实现WHILE循环)。这是我的密码:

.386
.model flat, stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
A WORD 9
B WORD 8
X WORD 15
sum WORD 0

.code
main PROC
L1:
    cmp X, 3     
    jne ELSEE   ;jump to ELSEE if X!=3 (short circuits the AND condition)
    mov ax, A+3
    cmp X, ax
    jle TRUE  ;jump to TRUE if X<=A+3
    mov bx, B-3
    cmp X, bx
    jl TRUE ;jump to TRUE if X<B-3
    cmp X,0
    jge WHYLE

    TRUE:
        sub X,2
        inc sum
    ELSEE:
        dec X
WHYLE:
    loop L1

    invoke ExitProcess, 0
main ENDP
END main
.386
.平板模型,标准球
.堆栈4096
ExitProcess原型,dwExitCode:DWORD
.数据
一个单词9
B单词8
X字15
和字0
.代码
主进程
L1:
cmp X,3
jne-ELSEE;跳转到ELSEE如果X=3(短路和状况)
移动轴,A+3
cmp X,ax

jle-TRUE;如果X则跳转为TRUE如果比较结果大于或等于,则跳转到开始,否则继续跳出循环,例如,跳转到退出调用。这是一个有效的解决方案,这在asm中是最自然的。由于无法提前轻松计算循环需要运行多少次迭代,因此不能使用
loop
指令作为循环条件

在循环体中还有其他错误,但这是如何循环的。您可能希望将
X
保存在寄存器中,而不是每次访问时都使用内存

    cmp X,0
    jl SKIP      ; skip the loop entirely if the condition is false to start with

L1:              ; do {

   ;;; loop body goes here
    
    cmp X,0
    jge L1       ; }while(X >= 0);
SKIP:

   ;; after the loop

由于您无法提前轻松计算迭代次数,因此不要使用
循环
。使用
testeax,eax
/
jge
作为循环分支来实现
while(x>=0)
逻辑。(EAX中有X)另外,
mov bx,B-3
是从地址
[B-3]
加载的一个字,这也不是你的伪代码所做的。@PeterCordes你能详细说明一下你对使用
测试
指令的第一个评论吗查看编译器输出的C版本的伪代码;e、 g.从带有
gcc-Og-m32
或MSVC的。(). 特别是对于测试/jge。将cmp/
jcc
用于循环与将其用于
if
没有根本区别,只是向后跳以重新运行循环体。是的,这是创建
while()
循环的标准方法。事实上,还有其他几个bug(比如if/else逻辑,以及执行内存偏移而不是load/add),因此最好去掉所有其他代码,只说“loop body goes here”,而不显示仍然错误的代码。