汇编语言制作一个运行 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 在您想要的地方。
尽可能避免使用 div
,it's about 30x slower than add
。
我是汇编语言编程的初学者,我正在寻求一些帮助来创建一个 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 在您想要的地方。
尽可能避免使用 div
,it's about 30x slower than add
。