汇编实现power函数

原创
2015/07/19 18:21
阅读数 344

这个函数改的深入理解程序设计 使用linux汇编语言里的例子。

相比书中的例子,主要改变为:

  1. 对底数为1。指数为1都进行特殊处理。

  2. 可以在64为平台编译通过,原书pushl %ebp 在64位平台编译不过,改为push %rbp。

  3. 原书使用exit系统调用查看结果,改为printf查看结果。

.section .data
.section .text

fmt: 
    .ascii "%ld\n\0"

.global _start
_start:
    push $24              #压入第2个参数
    push $2              #压入第1个参数
    call power           #调用函数
    add  $16, %rsp       #复位栈寄存器

    movslq %eax, %rsi    #把power函数的返回值保存到rsi寄存器中
    mov $fmt, %rdi       #把fmt 保存到rdi寄存器中
                         #printf(%rdi, %rsi);
    xor %rax, %rax
    call printf
    add $16, %rsp

    mov $0, %rdi         #exit(%rdi)
    call exit

.type power, @function
power:
    push %rbp            #保存基址寄存器
    mov %rsp, %rbp       #把栈指针寄存器的值保存到基址寄存器中

    movl 24(%rbp), %ecx  #取出函数第2个参数
    sub  $8, %rsp        #存放符号,第1个参数小于0 临时变量存放-1 否则存发1
    movq  $1, -8(%rbp)   #存发符号为的临时变量 先设置为1
    cmp  $0, 16(%rbp)    #和0比较
    jge first_args_lg0
    negl 16(%rbp)        #发现第一个参数小于0 取负 x = -x 此时的x >= 0
    movq  $-1, -8(%rbp)  #符号位设置为-1

first_args_lg0:
    
    mov 16(%rbp), %ebx   #取出函数第1个参数

    cmp $0, %ecx         #如果指数等于0 返回1. 任何数的0次方等于1
    je power_1          
    cmp $1, %ebx         #如果底数等于1 返回1. 任意多的1相乘还是1
    je power_1

    mov %ebx, %eax       #存放最后的结果值
    
power_loop_start:
    cmp $1, %ecx         #如果计算器等于1时,函数退出
    jle power_end
    imul %ebx, %eax
    dec %ecx             #对%eax里的值减1
    jmp power_loop_start

power_1:
    mov $1, %eax
power_end:
    imul -8(%rbp), %eax  #最终结果和符号位相乘
    mov %rbp, %rsp
    pop %rbp
    ret


编译:

gcc -c power.s -g && ld ./power.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 && ./a.out


展开阅读全文
打赏
0
6 收藏
分享
加载中
更多评论
打赏
0 评论
6 收藏
0
分享
返回顶部
顶部