汇编实现函数调用

x86_64 通过将函数参数存放在栈中的方式来实现参数传递。

asm 复制代码
# PURPOSE: Program to illustrate how functions work
#          This program will compute the value of
#          2^3 + 5^2
#

# Everything in the main program is stored in registers,
# so the data section doesn't have anything.
.section .data

.section .text

.globl _start
_start:
    push $3                                         # 将第二个参数入栈
    push $2                                         # 将第一个参数入栈
    call power                                      # 调用函数power,call会自动将函数返回地址入栈,
                                                    # 也就是下一条指令的地址
    add $16, %rsp                                   # move the stack pointer back,
                                                    # 通过移动栈顶指针的方式将保存在栈中的数据清理掉
    push %rax                                       # save the first answer before
                                                    # calling the next function
    push $2                                         # push second argument
    push $5                                         # push first argument
    call power                                      # call the function
    add $16, %rsp                                   # move the stack pointer back
    pop %rbx                                        # The second answer is already
                                                    # in %rax. We saved the
                                                    # first answer onto the stack,
                                                    # so now we can just pop it
                                                    # out into %rbx,将第二次计算的结果从栈中弹出存放到rbx寄存器中
    add %rax, %rbx                                  # add them together
                                                    # the result is in %rbx
    mov $1, %rax                                    # exit (%rbx is returned)
    int $0x80

# PURPOSE: This function is used to compute
#          the value of a number raised to
#          a power.
#
# INPUT:   First argument - the base number
#          Second argument - the power to
#          raise it to
#
# OUTPUT:  Will give the result as a return value
#
# NOTES:   The power must be 1 or greater
#
# VARIABLES:
#          %rbx - holds the base number
#          %rcx - holds the power
#
#          -8(%rbp) - 将计算后的结果放在栈中
#
#          %rax is used for temporary storage
#
.type power, @function
power:
    push %rbp                                   # 将旧的栈基址入栈
    mov %rsp, %rbp                              # 当前rsp指向旧的栈基址,获取传入参数时需要加上返回地址和旧栈基址的偏移
                                                # 因为存在两次入栈,一次是返回地址入栈,一次是rpb指针入栈
    sub $8, %rsp                                # 在栈中申请8字节用于存放计算结果的内存
    mov 16(%rbp), %rbx                          # 获取栈中传入的第一个参数,值存放在rbx
    mov 24(%rbp), %rcx                          # 获取栈中传入的第一个参数,值存放在rcx
    mov %rbx, -8(%rbp)                          # store current result

power_loop_start:
    cmp $1, %rcx                                # if the power is 1, we are done
    je end_power
    mov -8(%rbp), %rax                          # move the current result into %eax
    imul %rbx, %rax                             # multiply the current result by
                                                # the base number
    mov %rax, -8(%rbp)                          # 将计算结果更新到栈中
    dec %rcx                                    # decrease the power
    jmp power_loop_start                        # run for the next power

end_power:
    mov -8(%rbp), %rax                          # return value goes in %rax
    mov %rbp, %rsp                              # restore the stack pointer
    pop %rbp                                    # restore the base pointer
    ret

编译方式:as w_power.s -o w_power.o;ld w_power.o -o w_power

结果查看:执行w_power之后,echo $?查看计算结果。

使用专用寄存器来传递函数调用参数,rdi用来存放第一参数,rsi用来存放第二个参数,并且把第一计算的结果存放在栈中。

asm 复制代码
# PURPOSE: Program to illustrate how functions work
#          This program will compute the value of
#          2^3 + 5^2
#

# Everything in the main program is stored in registers,
# so the data section doesn't have anything.
.section .data

.section .text

.globl _start
_start:
    mov $2, %rdi                                    # 将第一个参数存入rdi
    mov $3, %rsi                                    # 将第二个参数存入rsi
    call power                                      # 调用函数power,call会自动将函数返回地址入栈,
                                                    # 也就是下一条指令的地址
    push %rax                                       # 将第一次计算的结果存放在栈中

    mov $5, %rdi                                    # 将第一个参数存入rdi
    mov $2, %rsi                                    # 将第一个参数存入rsi
    call power
    pop %rbx                                        # 获取第一次的计算结果
    add %rax, %rbx                                  # 第一次计算结果rbx与第二次计算结果rax的值相加
                                                    # the result is in %rbx
    mov $1, %rax                                    # exit (%rbx is returned)
    int $0x80

# PURPOSE: This function is used to compute
#          the value of a number raised to
#          a power.
#
# INPUT:   First argument - the base number
#          Second argument - the power to
#          raise it to
#
# OUTPUT:  Will give the result as a return value
#
# NOTES:   The power must be 1 or greater
#
# VARIABLES:
#          %rdi - 第一个参数
#          %rsi - 第二个参数
#
#          -8(%rbp) - 将计算后的结果放在栈中
#
#          %rax is used for temporary storage
#
.type power, @function
power:
    push %rbp                                   # 将旧的栈基址入栈
    mov %rsp, %rbp                              # 当前rsp指向旧的栈基址,获取传入参数时需要加上返回地址和旧栈基址的偏移
                                                # 因为存在两次入栈,一次是返回地址入栈,一次是rpb指针入栈
    sub $8, %rsp                                # 在栈中申请8字节用于存放计算结果的内存
    mov %rdi, -8(%rbp)                          # store current result

power_loop_start:
    cmp $1, %rsi                                # if the power is 1, we are done
    je end_power
    mov -8(%rbp), %rax                          # move the current result into %eax
    imul %rdi, %rax                             # multiply the current result by
                                                # the base number
    mov %rax, -8(%rbp)                          # 将计算结果更新到栈中
    dec %rsi                                    # decrease the power
    jmp power_loop_start                        # run for the next power

end_power:
    mov -8(%rbp), %rax                          # return value goes in %rax
    mov %rbp, %rsp                              # restore the stack pointer
    pop %rbp                                    # restore the base pointer
    ret
相关推荐
极客互动API3 天前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
wechatbot8889 天前
极客互动企业微信 SCRM 私域运营实战效果全景
大数据·汇编·微信·自动化·企业微信·rpa
祈禾14 天前
计算机组成原理之编译、汇编、链接、解释
开发语言·汇编·笔记·学习
水饺编程16 天前
AT&T 汇编语言学习笔记开篇语
c语言·汇编·c++
iCxhust16 天前
8088单板机VScode集成开发环境使用方法二(汇编版)
汇编·单片机·微机原理·8088单板机
·薯条大王16 天前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
txg66617 天前
VULOC:基于汇编切片的漏洞定位框架,精准锁定二进制中的危险代码
汇编·人工智能·深度学习·安全·网络安全
sunburn-18 天前
Java 队列全面详解:从入门到面试实战
java·开发语言·汇编·ide·idea
wechatbot88825 天前
企业微信API开发:登录-联系人查询-消息发送完整开发流程分享
汇编·微信·自动化·企业微信·ai编程·rpa
00后程序员张1 个月前
iOS加固技术路线全面解析:Bitcode模式、源码模式与汇编模式对比及爱加密优势
android·汇编·ios·小程序·uni-app·cocoa·iphone