Loops 在内部循环-程序集中以0开始外部递增值
我想把一个5x5位矩阵复制到外设上。我遇到的问题是,我不能用0作为行增量变量启动列循环。在高层,它将是这样的(非常简单):Loops 在内部循环-程序集中以0开始外部递增值,loops,assembly,x86,increment,Loops,Assembly,X86,Increment,我想把一个5x5位矩阵复制到外设上。我遇到的问题是,我不能用0作为行增量变量启动列循环。在高层,它将是这样的(非常简单): 加法R2,1是一个大问题,但是我应该把它放在哪里,这样它就不会以1开头呢?我真的不明白你在建议的程序集实现中说了什么/做了什么。当循环应该从0开始时,为什么要将寄存器初始化为1 但是嵌套在另一个for循环中的for循环编写起来相对简单,所以让我们从头开始,从高级C代码开始,一步一步地进行: for (line=0;line<4;line++) for (col
加法R2,1是一个大问题,但是我应该把它放在哪里,这样它就不会以1开头呢?我真的不明白你在建议的程序集实现中说了什么/做了什么。当循环应该从0开始时,为什么要将寄存器初始化为1 但是嵌套在另一个for循环中的for循环编写起来相对简单,所以让我们从头开始,从高级C代码开始,一步一步地进行:
for (line=0;line<4;line++)
for (column=0;column<4;column++)
请记住,您可以为循环计数器选择不同的寄存器。我只是随意选择了
EAX
和EDX
。如果您要在循环体内部调用一个函数,该函数对行和列执行某些操作,并且该函数希望在不同的寄存器中传递其参数,那么您也可以使用这些寄存器作为循环计数器
请注意,有一种编写此代码的略为优化的方法,可以消除
cmp
指令。我们可以从终点开始倒数,而不是从0开始倒数(这需要我们做一个比较,看看我们是否已经到达终点)。然后,我们只需利用以下事实:dec
指令在结果为0时设置零标志(ZF
),直接在该标志上分支,而不必进行比较。代码比解释更容易理解:
mov eax, 4 ; line = 4
.LineLoop:
mov edx, 4 ; column = 4
.ColumnLoop:
; Do something with line (EAX) and column (EDX).
; ...
dec edx ; --column
jnz .ColumnLoop ; keep looping if column > 0
dec eax ; --line
jnz .LineLoop ; keep looping if line > 0
; We are now finished with both loops.
唯一的问题是,您正在向后循环行和列。不过,这通常不是问题。(请参见如何通过while
重写,这应该更类似于组件变量)
for (line=0;line<4;line++)
for (column=0;column<4;column++)
xor eax, eax ; line = 0
.LineLoop:
; Do something with line (EAX).
; ...
inc eax ; ++line
cmp eax, 4
jb .LineLoop ; keep looping if line < 4
; We are now finished with the loop.
xor edx, edx ; column = 0
.ColumnLoop:
; Do something with column (EDX).
; ...
inc edx ; ++column
cmp edx, 4
jb .ColumnLoop ; keep looping if column < 4
; We are now finished with the loop.
xor eax, eax ; line = 0
.LineLoop:
xor edx, edx ; column = 0
.ColumnLoop:
; Do something with line (EAX) and column (EDX).
; ...
inc edx ; ++column
cmp edx, 4
jb .ColumnLoop ; keep looping if column < 4
inc eax ; ++line
cmp eax, 4
jb .LineLoop ; keep looping if line < 4
; We are now finished with both loops.
mov eax, 4 ; line = 4
.LineLoop:
mov edx, 4 ; column = 4
.ColumnLoop:
; Do something with line (EAX) and column (EDX).
; ...
dec edx ; --column
jnz .ColumnLoop ; keep looping if column > 0
dec eax ; --line
jnz .LineLoop ; keep looping if line > 0
; We are now finished with both loops.