在代码段中用“;”表示注释
汇编代码如下:
dp@dp:~ % cat test1.s
.section .rodata
output:
.asciz "the number is %d\n"
.section .data
value:
.int 0,0,0,0,0,0,0,0,0,0
.section .text
.globl main
main:
movl $0,%ecx
loopset:
;基地址(存在寄存器中的偏移地址,存在寄存器中的数据元素索引,存在寄存器中的数据元素大小)
movl %ecx,value(,%ecx,4)
inc %ecx
cmpl $10,%ecx
jne loopset
movl $0,%ecx
loopprint:
movl value(,%ecx,4),%eax
pushl %ecx
pushl %eax
pushl $output
call printf
add $8,%esp
popl %ecx
inc %ecx
cmpl $10,%ecx
jne loopprint
编译并运行
dp@dp:~ % gcc -o test1 test1.s
dp@dp:~ % ./test1
the number is 0
the number is 1
the number is 2
the number is 3
the number is 4
the number is 5
the number is 6
the number is 7
the number is 8
the number is 9
上述代码 ,先在.data可读写区域放置10个初始值为0的int值,然后在程序中通过loopset标记和jne语句完成一个循环,将它们的值依次赋值为0到9,最后通过loopprint标记和jne语句完成循环,调用c库的print语句将这些数输出。
inc表示自增1,而dec表示自减1 。饮品店加盟www.qidouzl.com
栈是由高地址向低地址增长的,当栈增加内容,将导致栈顶指针减少,否则,导致栈顶指针增加
在print语句执行返回后,清空执行print在堆栈中的生成垃圾,add $8,%esp,抛弃为调用printf函数准备的参数 ,栈顶有ESP寄存器来定位,压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大,因此这里相当于直接弹出压入的2个%eax(指向需要输出的数据)和$output参数,前面有调用:
pushl %eax
pushl $output
在上面这2个压栈之前,还调用了
pushl %ecx
其作用在于,保存%ecx的值,因为c库的printf函数会破坏%ecx寄存器的值,一般使用堆栈来保存可能被破坏的值,执行完printf完毕后,再还原:popl %ecx
原文:http://www.cnblogs.com/jiangyea/p/3557054.html