String x86 ASM Linux-创建循环

String x86 ASM Linux-创建循环,string,assembly,x86,nasm,String,Assembly,X86,Nasm,我正在Linux操作系统上使用NASM和x86 Intel汇编语法编写一个程序,应该很简单 我遇到的问题是,我无法为我的程序创建工作循环: section .data hello: db 'Loop started.', 0Ah ;string tells the user of start sLength: equ $-hello ;length of string notDone: db 'Loop not finished

我正在Linux操作系统上使用NASM和x86 Intel汇编语法编写一个程序,应该很简单

我遇到的问题是,我无法为我的程序创建工作循环:

section .data
    hello:    db 'Loop started.', 0Ah   ;string tells the user of start
    sLength:  equ $-hello               ;length of string

    notDone:  db 'Loop not finished.', 0Ah ;string to tell user of continue
    nDLength: equ $-notDone                ;length of string

    done:     db 'The loop has finished', 0Ah ;string tells user of end
    dLength:  equ $-done                      ;length of string

section .text

    global _start:
_start:
    jmp welcome         ;jump to label "welcome"

    mov ecx, 0          ;number used for loop index
    jmp loop            ;jump to label "loop"

    jmp theend          ;jump to the last label

welcome:

    mov eax, 4
    mov ebx, 1
    mov ecx, hello
    mov edx, sLength
    int 80              ;prints out the string in "hello"

loop:
    push ecx            ;put ecx on the stack so its value isn't lost

    mov eax, 4
    mov ebx, 1
    mov ecx, notDone
    mov edx, nDLength
    int 80              ;prints out that the loop isn't finished

    pop ecx             ;restore value
    add ecx, 1          ;add one to ecx's value
    cmp ecx, 10
    jl loop             ;if the value is not ten or more, repeat

theend:

;loop for printing out the "done" string
我正在打印第一个字符串,一个“未完成”,最后一个字符串打印;我又错过了9个“未完成”的!有人知道我为什么会失去ecx寄存器的值吗


谢谢。

您正在将循环寄存器ecx初始值设置为地址“hello”,而不是0:

    jmp welcome
    (mov ecx, 0)        ;number used for loop index <- jumped over
    ...
welcome:
    ...
    mov ecx, hello <- setting
    int 80         <- ecx
    ...
loop:
    push ecx            ;put ecx on the stack so its value isn't lost
jmp欢迎您
(mov-ecx,0);用于循环索引的编号
这意味着JMP下面的所有代码都不会被执行,特别是mov ecx,0(对于较短的指令,它应该是xor ecx,ecx

不要从跳转开始,从一些代码开始。JMP是一个跳转,它不会在跳转后返回,它只是继续执行

因此,在跳转到欢迎:,您直接转到循环:,从而丢失ecx=0代码

cmp ecx, 10
jl loop
ECX不是0,它肯定大于10h,因此不进行循环

试试这个:

_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, hello
    mov edx, sLength
    int 80              ;prints out the string in "hello"
    xor ecx,ecx         ;ecx = 0

loop:
    push ecx            ;save loop index
    mov eax, 4
    mov ebx, 1
    mov ecx, notDone
    mov edx, nDLength
    int 80              ;prints out that the loop isn't finished

    pop ecx             ;get loop index back in ECX
    add ecx, 1          ;add one to ecx's value
    cmp ecx, 10
    jl loop             ;if the value is not ten or more, repeat

theend:

我不明白;我看不出我的代码和你的代码有什么不同。我想我明白你想说的,但我不明白该如何改变,因为这是你的代码。您使用的是ecx中第一个int 80之后的任何内容作为初始循环值,而不是0.mov ecx,0实际上从未执行。寄存器是由int 80更改的,还是在int 80之后的ecx中的“hello”地址?@Jens Björnhager:EAX将随返回值更改。其他寄存器保持不变。(当然,EIP除外)堆栈不会更改。可能使用除#4之外的其他函数时,某些寄存器可能会在调用后更改。下面的链接很好地解释了在linux和int80上是如何进行系统调用的:在我的程序流程中,这些都是一些令人伤心的心理错误。非常感谢你。
_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, hello
    mov edx, sLength
    int 80              ;prints out the string in "hello"
    xor ecx,ecx         ;ecx = 0

loop:
    push ecx            ;save loop index
    mov eax, 4
    mov ebx, 1
    mov ecx, notDone
    mov edx, nDLength
    int 80              ;prints out that the loop isn't finished

    pop ecx             ;get loop index back in ECX
    add ecx, 1          ;add one to ecx's value
    cmp ecx, 10
    jl loop             ;if the value is not ten or more, repeat

theend: