堆栈是向下拓展的
一个很简单的例子,将两个32字节的数字压入堆栈,查看esp堆栈寄存器前后的变化。
.section .text
.global main
main:
nop
pushl $1
pushl $2
调试查看:
[edemon@CentOS workspace]$ gcc -gward -o pushpop pushpop.s
[edemon@CentOS workspace]$ gdb pushpop
...
(gdb) b *main+1
Breakpoint 1 at 0x80483ed: file pushpop.s, line 5.
(gdb) r
Starting program: /home/edemon/workspace/pushpop
Breakpoint 1, main () at pushpop.s:5
5 pushl $1
(gdb) p $esp
$5 = (void *) 0xbffff4dc
(gdb) n
main () at pushpop.s:6
6 pushl $2
(gdb) n
0x080483f1 in main ()
(gdb) p $esp
$6 = (void *) 0xbffff4d4
可以发现前后的esp寄存器地址值相差8,且数值变小。
函数调用call
用简单的函数调用计算2^4
.section .data
result:
.asciz "the result is %d\n"
.section .text
.globl main
main:
nop
movl $2,%eax
call func
call func
call func
pushl %eax
pushl $result
call printf
pushl $0
call exit
func:
pushl %ebp
movl %esp,%ebp
add %eax,%eax
movl %ebp,%esp
popl %ebp
ret
loop
loop指令自动使用ECX寄存器作为计数器,每一次迭代过程中递减并测试这个计数器。
下面的程序用于计算2^5:
# calculate 2^5
.section .data
output:
.asciz "2^5 is %d\n"
.section .text
.global main
main:
movl $4,%ecx
movl $2,%ebx
myloop:
addl %ebx,%ebx
loop myloop
pushl %ebx
pushl $output
call printf
addl $8,%esp #clear stack
movl $0,%ebx
movl $1,%eax #sys_exit
int $0x80
for循环
计算前20位的斐波纳契
代码:
.section .data
values:
.int 1,1
#output:
# .asciz "num = \n"
.section .text
.globl main
main:
nop
movl $0,%ecx
loop:
movl $0,%eax #eax is next feibo element.
add values(,%ecx,4),%eax
add $1,%ecx
add values(,%ecx,4),%eax
add $1,%ecx
movl %eax,values(,%ecx,4)
sub $1,%ecx
cmp $18,%ecx #if ecx < 18
jle loop
nop
gdb查看内存:
[edemon@CentOS workspace]$ gdb feibo1
(gdb) b 21
Breakpoint 1 at 0x804841a: file feibo1.s, line 21.
(gdb) r
Starting program:
Breakpoint 1, loop () at feibo1.s:21
21 nop
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.i686
(gdb) x/20 &values
0x8049684 <values>: 1 1 2 3
0x8049694 <completed.6190>: 5 8 13 21
0x80496a4: 34 55 89 144
0x80496b4: 233 377 610 987
0x80496c4: 1597 2584 4181 6765
if分支
写一个简单的if分支语句,用于处理1和2的比较。
.section .data
str1:
.asciz "1 <= 2."
len1 = . - str1
str2:
.asciz "1 > 2."
len2 = . - str2
.section .text
.global main
main:
movl $1,%ecx
movl $2,%edx
cmpl %edx,%ecx
jle L1
movl $len2,%edx
movl $str2,%ecx
jmp end
L1:
movl $len1,%edx
movl $str1,%ecx
jmp end
end:
movl $1,%ebx