直接寻址方式:
movl ADDRESS, %EAX 将地址ADDRESS里的值加载到%eax
索引须知方式:
movl string_start(,%ecx,1), %eax
从string_start处开始,将该地址于1*%ecx相加,并将所得值加载到%eax
间接寻址方式:
movl (%eax), %ebx 将%eax里的值加载到%ebx
基址寻址方式:
movl 4(%eax), %ebx 将%eax + 4加载到%ebx
立即数寻址方式:
movl $12, %eax 将数12加载到%eax
#深入理解程序设计——linux汇编的示例
.code32
.section .data
.section .text
.globl _start
_start:
pushl $3
pushl $2
call power
addl $8, %esp #将栈指针后移
pushl %eax #调用下一个函数前保存第一个答案
pushl $2
pushl $5
call power
addl $8, %esp
popl %ebx #第二个答案已经在%eax中了,现在将第一个答案弹到%ebx
addl %eax, %ebx
movl $1, %eax
int $0x80
#函数
.type power, @function
power:
pushl %ebp #保存旧栈底 call的时候已经将下一条指令的地址压栈了
movl %esp, %ebp #栈底指针指向栈顶
subl $4, %esp #开辟新的栈空间
movl 8(%ebp), %ebx
movl 12(%ebp), %ecx
movl %ebx, -4(%ebp) #储存当前结果
power_loop_start:
cmpl $1, %ecx #如果是1次方,那么已经得到结果
je end_power
movl -4(%ebp), %eax #将当前结果移入%eax
imull %ebx, %eax #将当前结果和底数相乘
movl %eax, -4(%ebp) #保存当前结果
decl %ecx #指数减1
jmp power_loop_start #为减后的指数进行幂运算
end_power:
movl -4(%ebp), %eax #将返回值移入%eax
movl %ebp, %esp #恢复原栈顶
popl %ebp #恢复原栈底
ret
运行会出现段错误
用gdb查看运行
n运行到这里是出现rdi rsi rdx rcx,不知道什么意思
然后再按n
提示分段错误,下面显示不能读取内容0xffffe34c
就无法继续运行了.
这里是用64位的系统编译了32位的程序
用32位的编译命令就不会出现错误
zqy@ubuntu:~/Desktop/深入理解程序设计Lnux汇编/4.4$ as -32 power.s -o power.o
zqy@ubuntu:~/Desktop/深入理解程序设计Lnux汇编/4.4$ ld -m elf_i386 power.o -o power
zqy@ubuntu:~/Desktop/深入理解程序设计Lnux汇编/4.4$ ./power
zqy@ubuntu:~/Desktop/深入理解程序设计Lnux汇编/4.4$ echo $?