我只是从组装开始,我掌握了诸如puts和strlen的一些基本知识,但是其中一些概念没有意义。
我正在尝试实现一个基本循环并在每次迭代时打印计数器。到目前为止,这是我的代码:
%include 'functions.asm' ;contains print and exit
section .data
msg db 'loop', 0x0a, 0x00
section .bss
section .text
global _start
_start:
mov ecx, 0
repeat:
cmp ecx, 10
jz done
push ecx ;line 18
mov ecx, msg ;line 19
call print
pop ecx ;line 21
inc ecx
jmp repeat
done:
call exit
这有效。但是输出是“ loop \ n” n次。我正在尝试获取'0 \ n1 \ n2 \ n3 \ n .... n \ n'。
到目前为止,这是我尝试过的: -删除第18、19和21行。Segfaults,不确定原因。 -将第19行替换为添加ecx“ 0”。 Segfault也是如此。
此外,我不确定cmp为何起作用。我不应该将寄存器中的值与cmp byte [ecx]而不是10进行比较吗? 与inc相同,它增加了ecx中包含的值?因此,如果我使用inc [ecx],则1,它将增加ecx内部包含的地址的值吗?因此,xor ecx,ecx,inc [ecx],1应该将内存地址0x00000000的值增加1吗?
答案 0 :(得分:1)
显然,您有一些自定义的print
函数,该函数可打印ecx
指向的字符串。您可能具有print_int
或可以直接使用的类似功能。如果不是,那么通过添加'0'
可以使您处在正确的轨道上,但是您需要将字符串放入内存中并向其传递指针。一种可能的解决方案:
%include 'functions.asm' ;contains print and exit
section .data
msg db '#', 0x0a, 0x00 ; the # is a placeholder for the digit
section .text
global _start
_start:
mov ecx, 0
repeat:
cmp ecx, 10
je done
push ecx
add cl, '0'
mov [msg], cl
mov ecx, msg
call print
pop ecx ;line 21
inc ecx
jmp repeat
done:
call exit
使用文本进行计数的简单得多的版本:
%include 'functions.asm' ;contains print and exit
section .data
msg db '0', 0x0a, 0x00
section .text
global _start
_start:
mov ecx, msg
repeat:
call print
inc byte [msg]
cmp byte [msg], '9'
jbe repeat
done:
call exit
对于其他问题,是的,[]
表示内存引用,因此如果要直接在寄存器上进行操作,请不要使用它。