在Assembly x86中进行for循环

时间:2017-10-23 16:44:49

标签: linux assembly

我是Assembly的新手,我想知道如何编写一个迭代15次的for循环。在for循环中,我需要有一个if条件,测试是否整数k大于7。如何用代码编写?

2 个答案:

答案 0 :(得分:3)

通常这会被写成评论,但有点过于复杂。另一个答案中的代码效率不高:

    MOV ECX, 15   ; number of iterations
.loop:
    ...
    CMP EAX, 8    ; compare k to 7
    DEC ECX          ; partial-flag merge needed after this, slow on some CPUs
    JA .loop      ; check for loop exit condition
B:                ; code after the loop
    ...
    ;; check CF here to see if k >= 8 or not, i.e. k > 7

编辑:要使内存中的k与以前一样为32位整数,CMP指令如下所示:

    CMP DWORD [k], 8

EDIT2:保存一个条件跳转。当k大于7时,OP没有提及离开或停留。上述代码在运行15次或k不大于7时离开循环。

请注意,结合比较的这个技巧只有在Intel Sandybridge-family或Silvermont这样的CPU上才有用,它们在dec之后没有部分标记停顿来读取CF.在Core2 / Nehalem上,这将停止约7个周期以使用dec合并标志like you'd get in an adc BigInteger loop。请参阅Agner Fog's microarch PDF

除非您确定在代码运行的所有CPU上运行良好,否则请与cmp / ja分开使用jaedec / jnz

EDIT3:当eax大于/小于7时,OP要求递增/递减整数(此处为edx):

.loop:
    ...
    CMP EAX, 7
    DEC EDX
    JB .end
    INC EDX
    JE .end
    INC EDX
.end:
    DEC ECX
    JZ .loop

(可能会有人进一步优化这一点)

答案 1 :(得分:-3)

我建议学习如何使用编译代码来教你这些东西。在C中编写所需的代码,然后使用flags编译它以输出程序集。例如,在gcc中,这是使用-S标志完成的。然后,您可以阅读机器生成的汇编代码,以了解它是如何完成的。

for循环的一般策略可能是这样的:

       MOV ECX, 0    ; clear ECX
   A:    
       CMP [k], 7    ; compare k to 7
       JGT B         ; jump to B if k is greater than 7
       CMP ECX, 15   ; check for loop exit condition
       JE C          ; jump to C if we have iterated 15 times
       INC ECX
       JMP A
   B:            ; this happens if K is greater than 7
   ...
   C:            ; this happens if we reach the end of the loop