汇编实现power函数

这个函数改的深入理解程序设计 使用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         #printf(%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
时间: 2024-10-11 07:15:57

汇编实现power函数的相关文章

SGI STL的 power 函数之个人理解

SGI STL的power函数用于计算某数的n次方 例如求 x的n次幂 n = 20 (20 二进制 10100) 1 0 1 0 0 20 = 2^4 + 2^2 x^20 = x^((2^4) + (2^2)) = x^( 2^4 ) * x ^( 2^2) part2 part1 template <class _Tp, class _Integer, class _MonoidOperation> _Tp __power(_Tp __x, _Integer __n, _MonoidOp

奇怪的 sql server 2008 Power 函数

bigint 的 数据范围是  从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据 但是 , 如果这么写 print CAST(POWER(3, 20) AS BIGINT) 会报这个错误 Msg 232, Level 16, State 3, Line 1 Arithmetic overflow error for type int, value = 3486784401.000000. 尽管 34867844

power函数

#include<stdio.h>#include<math.h>//power函数double power(double x,double y);int main(){ double x = 2.0, y = 3.0, z; z = power(x, y); printf("%f\n",z); while (1); return 0;} double power(double x, double y){ double z = 1.0; while (y) {

从汇编看c++函数的默认参数

在c++中,可以为函数提供默认参数,这样,在调用函数的时候,如果不提供参数,编译器将为函数提供参数的默认值.下面从汇编看其原理. 下面是c++源码: int add(int a = 1, int b = 2) {//参数a b有默认值 return a + b; } int main() { int c= add();//不提供参数 } 下面是mian函数里面的汇编码: ; 4 : int main() { push ebp mov ebp, esp push ecx;为局部变量c分配了4字节的

汇编调用c函数为什么要设置栈

之前看了很多关于uboot分析类的文章,其中提到为C语言的运行准备栈.而在uboot start.S汇编代码中,关于系统初始化,也看到栈指针初始化,即正确给栈指针sp赋值,却从来没看到有人解释,为何要这样做.接下来,我试图解释这个问题.首先了解栈的作用.关于这个,详细讲解要很长的篇幅,故此处只做简略介绍. 总的来说,它的作用就是:保存现场/上下文,传递参数,保存临时变量 1.保存现场/上下文 现场/上下文相当于案发现场,总有一些案发现场,要记录下来,否则被别人破坏,便无法恢复.而此处说的现场,是

汇编实现square函数

square函数主要计算一个数的平方 code: .section .data .section .text .global _start fmt:     .ascii "%d\n\0" _start:     pushq $2     call square     addq $8, %rsp               #复位%rsp     movl %eax, %esi         movq $fmt, %rdi         xorl %eax, %eax      

power函数的非递归经典实现(时间复杂度仅仅为logn)

#include<iostream> using namespace std; template <class T,class Integer> T power(T x,Integer n) { if(n == 0) return 1; if(n == 1) return x; while((n&1) == 0) { x = x*x; n >>= 1; } T result = x; n >>= 1; while(n != 0) { x = x*x;

【逆向知识】堆栈图-汇编中的函数

push ebp ; 提升堆栈 mov ebp,esp sub esp,0CCh ------------------------------------------ push ebx ; 保留现场,函数在执行的时候会用到一些寄存器,但这些寄存器中 push esi ; 值很可能会被程序用到,所以要先存储到内存中 push edi push ecx ------------------------------------------ lea edi,[ebp-0CCh] ; 向分配的空间填充数据

IAR EWAR 内联汇编 调用外部函数 Error[Og005], Error[Og006]

How do I call a C function in another module from inline assembler in IAR EWARM? I have a bit of assembly in a hard fault handler. The assembly is basically meant to pass the current stack pointer as a parameter (in R0). It looks like so... __asm(" m