汇编语言循环只进行一次迭代?

时间:2016-06-03 00:08:08

标签: loops gcc assembly gnu

整天都在做这项任务,无法弄清楚我做错了什么。我的代码应该使用嵌套循环来打印这样的东西:

xxxxxxxxxx
xxxxxxxxx
xxxxxxxx
xxxxxxx
xxxxxx
xxxxx
xxxx
xxx
xx
x

我为此编写的代码是:

# printStars2.s

# Useful constants
    .equ STDOUT,1
# Stack frame
    .equ theChar,-1
    .equ counter,-8
    .equ lineCounter, -16
    .equ localSize,-32
newline:
    .string "\n"
    .equ newlineSz,.-newline-1          # equate msgSz to # of chars

# Code
    .text
    .globl main
    .type main, @function
main:
    pushq %rbp # save base pointer
    movq %rsp, %rbp # set new base pointer
    addq $localSize, %rsp # for local var.

    movb $'*', theChar(%rbp) # character to print
    movl $10, counter(%rbp) # innerLoop control variable
    movl $10, lineCounter(%rbp) #outerLoop control variable

outerLoop:
    jmp innerLoop          # jumps to innerLoop
    decl lineCounter(%rbp) # lineCounter--
    movl lineCounter(%rbp), %ebx #copies lineCounter value to intermediate register
    movl %ebx, counter(%rbp) # copies lineCounter value from register to innerLoop counter
    cmpl $0, lineCounter(%rbp) #checks if outerLoop has gone through 10 iterations
    jne outerLoop #repeat if not
    jmp exitLoop #exitLoop when complete

innerLoop:
    leaq theChar(%rbp), %rsi # address of char
    movl $1, %edx # one character
    movl $STDOUT, %edi # standard out
    call write # invoke write function
    decl counter(%rbp) # counter--;
    jg innerLoop # repeat if > 0
    #newLine
    movl    $newlineSz, %edx        # message size
    movl    $newline, %esi          # address of message text string
    movl    $STDOUT, %edi       # standard out
    call    write               # invoke write function

exitLoop:
    movl $0, %eax # return 0;
    movq %rbp, %rsp # restore stack pointer
    popq %rbp # restore base pointer
    ret

当我运行它时,它只会出现一次循环,它只打印一行10颗星。如果有人能告诉我我做错了什么或者指出了我正确的方向,我会非常感激。

1 个答案:

答案 0 :(得分:0)

输入outerLoop后,您会跳转到innerLoop

在那里打印星星并循环,直到计数器达到0(第37-42行)。

然后打印换行符(第44-47行)。

然后你回来,程序结束。

你决不跳回outerLoop,所以没有循环!

一种解决方案:将jmp innerLoop指令替换为内循环的内容。然后,当内循环完成后,它将继续执行您为外循环编写的逻辑,一切都会正常工作。由于您的标签outerLoop:innerLoop:将紧挨着彼此,您可以将它们组合在一起,只需Loop:

organization也不需要跳转到exitLoop。