Ber*_*ard 7 assembly gnu-assembler
这有点奇怪,但今天我正在寻找GNU汇编程序(我希望能够至少阅读语法),并且试图让我的这个有点人为的例子工作.也就是说我只想从0到100,一直打印数字.几分钟后,我想出了这个:
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
movl $0, %eax # The starting point/current value.
movl $100, %ebx # The ending point.
_loop:
# Display the current value.
pushl %eax
pushl $string
call _printf
addl $8, %esp
# Check against the ending value.
cmpl %eax, %ebx
je _end
# Increment the current value.
incl %eax
jmp _loop
_end:
Run Code Online (Sandbox Code Playgroud)
我从中得到的只是一遍又一遍地打印出来.就像我说的,只是一个有点人为的例子,所以不要太担心它,这不是生死攸关的问题.
(格式有点混乱,但没什么大不了的).
sea*_*boy 12
你无法相信任何被调用的程序对任何寄存器的作用.将寄存器压入堆栈并在调用printf后将其弹回,或者将增量和终点值保存在存储器中,并根据需要读/写寄存器.
我希望以下工作.我假设pushl有一个等价的popl,你可以将多个数字推到堆栈上.
# count.s: print the numbers from 0 to 100.
.text
string: .asciz "%d\n"
.globl _main
_main:
movl $0, %eax # The starting point/current value.
movl $100, %ebx # The ending point.
_loop:
# Remember your registers.
pushl %eax
pushl %ebx
# Display the current value.
pushl %eax
pushl $string
call _printf
addl $8, %esp
# reinstate registers.
popl %ebx
popl %eax
# Check against the ending value.
cmpl %eax, %ebx
je _end
# Increment the current value.
incl %eax
jmp _loop
_end:
Run Code Online (Sandbox Code Playgroud)
我对_printf不太熟悉,但可能是它修改了eax吗?Printf应返回打印的字符数,在本例中为2:'0'和'\n'.我认为它在eax中返回,当你递增它时,你得到3,这就是你要打印的内容.你可能最好为计数器使用不同的寄存器.
您可以安全地使用"被调用者保存"的寄存器,而无需自己保存.在x86上,这些是edi,esi和ebx; 其他架构有更多.
这些内容记录在ABI参考文献中:http://math-atlas.sourceforge.net/devel/assembly/