汇编语言制作一个运行 n/10 次的 for 循环

Assembly language making a for loop that runs n/10 times

我是汇编语言编程的初学者,我正在寻求一些帮助来创建一个 n/10 秒内 运行s 的 for 循环。

我无法理解如何将此 Java for 循环转换为汇编语言 for 循环。 N 是用户输入的值。 for(i = 1; i<= n; i++)

我的方向是否正确? 如果我不对,那我哪里出错了? 我只是想让循环正常工作,稍后我会担心 运行。

代码:

.586
.MODEL FLAT

INCLUDE io.h            ; header file for input/output

.STACK 4096

.DATA

number1 DWORD   ?

sum DWORD   ?

prompt1 BYTE    "Enter a number between 1-100", 0

string  BYTE    40 DUP (?)

.CODE

_MainProc PROC

    input   prompt1, string, 40      ; read ASCII characters
    atod    string          ; convert to integer
    mov     ecx, eax    ; store input to memory this is n
    mov     eax, 0  ; //set eax to 0
    mov     edx, 0  //This is sum
    mov ebx, 1      //Create i
    cmp ecx, ebx    //compare i to n
    jnle ecx        //jump when negative or less than ecx
    add edx, ebx    //adds i to sum
    inc ebx         //i++
    jmp ebx         //jump to ebx repeat
_MainProc ENDP

END                             ; end of source code

循环一小部分的最简单方法是在循环中加或减 10。

不是通过除法来获得迭代次数,而是在循环内重复减法。重复 add/sub 通常是 multiply/divide 的糟糕方法,但无论如何你都想循环那么多次,所以你使用 that 作为循环计数器。这称为 "strength reduction" 优化,因为除法比减法 "stronger"(slower/more 昂贵)。

实现此目的的一种方法是向下计数至零,并在计数器变为负数(有符号 less-than)时跳出循环,或者当它越过零(无符号进位)时跳出循环。

atod returns eax 中的结果所以你用 mov eax, 0.

破坏了它
    ... code to get input, and call atod
    ; atod return value in eax = n

    xor    edx, edx       ; sum = edx = 0

    ; loop n/10 times  (integer division truncates towards 0)
@loop:                    ; do {
    add    edx, eax         ; sum += i

    sub    eax, 10          ; i -= 10
    jnc    @loop          ; } while(i didn't wrap around);

    mov    eax, edx      ; eax=sum

或者用jg循环}while(i>0),或者用jge循环}while(i>=0)。添加零是一个no-op,所以我们可以让循环运行一次i=0,但是jg在这里会很好如果您不需要支持大于最大带符号 32 位整数的起始值。 (即如果你不需要未签名)。

如果你想向上循环,你可以用 compare-and-branch

    ... code to get input, and call atod
    ; atod return value in eax = n

    xor    edx, edx       ; sum = edx = 0
    mov    ecx, 1         ;   i = ecx = 1

    ; if the loop might need to run 0 times, test eax,eax / jz to the bottom.
    ; or cmp eax, 10 or whatever.
@loop:                    ; do {
    add    edx, ecx         ; sum += i

    add    ecx, 10          ; i += 10
    cmp    ecx, eax
    jb     @loop          ; } while(i < n);

    mov    eax, edx      ; eax=sum

根据需要进行调整以进行带符号的比较,或 jbe 进行 <= 或其他任何调整。

in big o notation of n/10.

O(n) 复杂度 类 不计算常数因子,因此 O(n) = O(n/10)。我假设你的意思是 "runs n/10 times" 就像你在标题中所说的那样,而不是 Java for 循环中的 n 次,或者 O(n) 次(这将允许任何 off-by-one 错误或常量乘数)。


如果您想要一个在循环中仅递增 1 的计数器,您可以对 loop-terminating 条件进行递减计数(趋向于零),然后对另一个寄存器进行递增计数。您的 Java 没有在任何地方显示 10 的因数,所以 IDK 在您想要的地方。

尽可能避免使用 divit's about 30x slower than add