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
在段的末尾使用,但似乎没有任何效果.我也搜索了分段错误,但我没有发现任何真正有用的东西.任何帮助将不胜感激,因为我是一个绝对的初学者.
它崩溃的原因可能是你的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)