Assembly 有没有办法在条件跳转(程序集x86)后返回并运行标签中的剩余代码?
因此,我目前正在为一门大学课程学习汇编,我很好奇是否有可能(特别是对于循环)返回到代码标签,并在跳转完成后运行循环的其余部分 例如,我正在尝试编写的程序要求每行10个数字,因此我想知道,如果找到10个数字,是否可以使用类似的方法创建新行,但还有更多的数字需要计算:Assembly 有没有办法在条件跳转(程序集x86)后返回并运行标签中的剩余代码?,assembly,x86,Assembly,X86,因此,我目前正在为一门大学课程学习汇编,我很好奇是否有可能(特别是对于循环)返回到代码标签,并在跳转完成后运行循环的其余部分 例如,我正在尝试编写的程序要求每行10个数字,因此我想知道,如果找到10个数字,是否可以使用类似的方法创建新行,但还有更多的数字需要计算: mov ECX, number find_primes: cmp col_number, 10 jg new_line *Then come back here nested_l
mov ECX, number
find_primes:
cmp col_number, 10
jg new_line
*Then come back here
nested_loop:
*fancy code that calculates prime numbers here*
*prints prime number on the current line
loop outside_loop ; starts all over again
new_line:
call CrLf
*return back to current spot?*
我知道这是一个粗略的psuedo代码,但希望它显示了我正在尝试做什么。任何帮助都将不胜感激。好吧,你可以跳回去,因为堆栈保持不变。但请确保使用/或更具体的
PUSH-reg
/POP-reg
组合保存call-CRLF
使用的寄存器
mov ECX, number
find_primes:
cmp col_number, 10
jg new_line
; Then come back here
return_label:
nested_loop:
*fancy code that calculates prime numbers here*
*prints prime number on the current line
loop outside_loop ; starts all over again
new_line:
; Save regs with PUSH
call CrLf
; Restore regs with POP
*return back to current spot?*
JMP return_label
这将适用于前10个数字。但是,您只能使用cmp colu number,10
检查计数是否大于10。第十一个要素之后还将有一个新的行。所以12号
因此,您需要另一种更精细的方法
一种简单的方法是对函数为的指令使用模运算
无符号除法EDX:EAX除以r/m32,结果存储在EAX中← 商← 剩余的
并返回EDX中的余数。在代码中,这可能如下所示:
mov ECX, number ; ECX = current number
mov EBX, 10 ; every 10th line
find_primes:
xor edx,edx ; clear upper 32-bits of the 64-bit value in EDX:EAX
mov eax, ecx ; EDX:EAX contains number
div ebx ; divide EDX:EAX by 10
cmp edx, 0 ; check if remainder in EDX is zero
jne nested_loop ; if not, skip CrLf code
; Save regs with PUSH
call CrLf
; Restore regs with POP
; Then come back here
nested_loop:
*fancy code that calculates prime numbers here*
*prints prime number on the current line
loop outside_loop ; starts all over again
这是一些伪代码,但您应该了解组装部件的要点。也许您需要先保存
EBX
寄存器,然后再恢复。这取决于您的环境。当然,使用另一个跳转,可能是无条件跳转。请注意,“在标签中”没有意义。标签不包含任何内容。他们只是在你的代码中做了标记。谢谢!这很有道理!呃,不要在循环中实际使用div
,使用一个向0倒计时的计数器,在打印CRLF的同时将计数器重置为9或10。因此,普通情况下的代码只是dec ebx
/jz handle\u special\u case
,然后是一个back\u from\u special\u case:
标签@科里约:像这样的asm FizzBuzz:(或相关:)是的。这是另一种可能性,它更像汇编,而不像C。更容易的是,通过测试test ecx,111b
为零,在每8个元素上进行破坏。