NASM装配时循环计数器

vro*_*oom 4 c assembly gcc loops nasm

我正在汇编中编写一个while循环,以便在Linux终端中使用nasm和gcc进行编译.程序比较x和y,直到y> = x,并报告结束时的循环次数.这是代码:

segment .data

out1    db "It took ", 10, 0
out2    db "iterations to complete loop. That seems like a lot.", 10, 0
x       db 10
y       db 2
count   db 0

segment .bss

segment .text

global main
extern printf

main:
    mov    eax, x
    mov    ebx, y
    mov    ecx, count
    jmp    lp         ;jump to loop lp

lp:
    cmp    ebx, eax   ;compare x and y
    jge    end        ;jump to end if y >= x
    inc    eax        ;add 1 to x
    inc    ebx        ;add 2 to y
    inc    ebx
    inc    ecx        ;add 1 to count
    jp     lp         ;repeat loop

end:

    push    out1      ;print message part 1
    call    printf

    push    count     ;print count
    call    printf

    push    out2      ;print message part 2
    call    printf

    ;mov    edx, out1               ;
    ;call   print_string            ;
                                    ;
    ;mov    edx, ecx                ;these were other attempts to print
    ;call   print_int               ;using an included file
                                    ;
    ;mov    edx, out2               ;
    ;call   print_string            ;
Run Code Online (Sandbox Code Playgroud)

这是在终端中编译和运行的:

nasm -f elf test.asm
gcc -o test test.o
./test
Run Code Online (Sandbox Code Playgroud)

终端输出如下:

It took
iterations to complete loop. That seems like a lot.
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

我看不出逻辑有什么问题.我认为这是语法,但我们只是刚刚开始学习汇编,我尝试了各种不同的语法,如围绕变量括号,并ret在段的末尾使用,但似乎没有任何效果.我也搜索了分段错误,但我没有发现任何真正有用的东西.任何帮助将不胜感激,因为我是一个绝对的初学者.

zne*_*eak 6

它崩溃的原因可能是你的main函数没有ret指令.另外一定要设置eax为0表示成功:

xor     eax, eax ; or `mov eax, 0` if you're more comfortable with that
ret
Run Code Online (Sandbox Code Playgroud)

此外,全局变量指定指针,而不是值.mov eax, x设置eax为的地址x.如果您想要发生任何事情(或不使用全局变量),您需要回写它.

最后,您使用printf单个非字符串参数进行调用:

push    count     ;print count
call    printf
Run Code Online (Sandbox Code Playgroud)

第一个参数需要是一个格式字符串,比如"%i".这里count是一个指向空字节的指针,所以你什么也得不到.我的头,你应该试试这个:

out3    db "%i ", 0

; snip

push    ecx
push    out3
call    printf
Run Code Online (Sandbox Code Playgroud)