汇编实现函数调用

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

# 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 functionpush $2                                         # push second argumentpush $5                                         # push first argumentcall power                                      # call the functionadd $16, %rsp                                   # move the stack pointer backpop %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 %rbxmov $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                          # 获取栈中传入的第一个参数,值存放在rbxmov 24(%rbp), %rcx                          # 获取栈中传入的第一个参数,值存放在rcxmov %rbx, -8(%rbp)                          # store current resultpower_loop_start:cmp $1, %rcx                                # if the power is 1, we are doneje end_powermov -8(%rbp), %rax                          # move the current result into %eaximul %rbx, %rax                             # multiply the current result by# the base numbermov %rax, -8(%rbp)                          # 将计算结果更新到栈中dec %rcx                                    # decrease the powerjmp power_loop_start                        # run for the next powerend_power:mov -8(%rbp), %rax                          # return value goes in %raxmov %rbp, %rsp                              # restore the stack pointerpop %rbp                                    # restore the base pointerret

编译方式:as w_power.s -o w_power.o;ld w_power.o -o w_power
结果查看:执行w_power之后,echo $?查看计算结果。

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

# 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                                    # 将第一个参数存入rdimov $3, %rsi                                    # 将第二个参数存入rsicall power                                      # 调用函数power,call会自动将函数返回地址入栈,# 也就是下一条指令的地址push %rax                                       # 将第一次计算的结果存放在栈中mov $5, %rdi                                    # 将第一个参数存入rdimov $2, %rsi                                    # 将第一个参数存入rsicall powerpop %rbx                                        # 获取第一次的计算结果add %rax, %rbx                                  # 第一次计算结果rbx与第二次计算结果rax的值相加# the result is in %rbxmov $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 resultpower_loop_start:cmp $1, %rsi                                # if the power is 1, we are doneje end_powermov -8(%rbp), %rax                          # move the current result into %eaximul %rdi, %rax                             # multiply the current result by# the base numbermov %rax, -8(%rbp)                          # 将计算结果更新到栈中dec %rsi                                    # decrease the powerjmp power_loop_start                        # run for the next powerend_power:mov -8(%rbp), %rax                          # return value goes in %raxmov %rbp, %rsp                              # restore the stack pointerpop %rbp                                    # restore the base pointerret

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503829.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医学图像分析工具02:3D Slicer || 医学影像可视化与分析工具 支持第三方插件

3D Slicer 是一款功能全面的开源医学影像分析软件,广泛应用于影像处理、三维建模、影像配准和手术规划等领域。它支持多种医学影像格式(如 DICOM、NIfTI)和丰富的插件扩展,是神经科学、放射学和生物医学研究中不可或缺的工具。 在…

STM32裸机开发转FreeRTOS教程

目录 1. 简介2. RTOS设置(1)分配内存(2)查看任务剩余空间(3)使用osDelay 3. 队列的使用(1)创建队列(1)直接传值和指针传值(2)发送/接收…

使用高云小蜜蜂GW1N-2实现MIPI到LVDS(DVP)转换案例分享

作者:Hello,Panda 大家晚上好,熊猫君又来了。 今天要分享的是一个简单的MIPI到LVDS(DVP)接口转换的案例。目的就是要把低成本FPGA的应用潜力充分利用起来。 一、应用背景 这个案例的应用背景是:现在还在…

Express 加 sqlite3 写一个简单博客

例图: 搭建 命令: 前提已装好node.js 开始创建项目结构 npm init -y package.json:{"name": "ex01","version": "1.0.0","main": "index.js","scripts": {"test": &q…

git撤回提交、删除远端某版本、合并指定版本的更改

撤回提交 vscode的举例 一、只提交了还未推送的情况下 1.撤回最后一次提交,把最后一次提交的更改放到暂存区 git reset --soft HEAD~12.撤回最后一次提交,把最后一次提交的更改放到工作区 git reset --mixed HEAD~13.撤回最后一次提交,不…

[Linux]redis5.0.x升级至7.x完整操作流程

1. 从官网下载最新版redis: 官网地址:https://redis.io/download 注:下载需要的登录,如果选择使用github账号登录,那么需要提前在github账号中取消勾选“Keep my email addresses private”(隐藏我的邮箱…

xss-labs关卡记录15-20关

十五关 随便传一个参数,然后右击查看源码发现,这里有一个陌生的东西,就是ng-include。这里就是: ng-include指令就是文件包涵的意思,用来包涵外部的html文件,如果包涵的内容是地址,需要加引号。…

数据库回滚:大祸临头时

原文地址 什么是数据库回滚? 数据库技术中,回滚是通过撤销对数据库所做的一项或多项更改,将数据库返回到先前状态的操作。它是维护数据完整性和从错误中恢复的重要机制。 什么时候需要数据库回滚? 数据库回滚在以下几个场景中很…

年会抽奖Html

在这里插入图片描述 <!-- <video id"backgroundMusic" src"file:///D:/background.mp3" loop autoplay></video> --> <divstyle"width: 290px; height: 580px; margin-left: 20px; margin-top: 20px; background: url(D:/nianhu…

基于FPGA的出租车里程时间计费器

基于FPGA的出租车里程时间计费器 功能描述一、系统框图二、verilog代码里程增加模块时间增加模块计算价格模块上板视频演示 总结 功能描述 &#xff08;1&#xff09;&#xff1b;里程计费功能&#xff1a;3公里以内起步价8元&#xff0c;超过3公里后每公里2元&#xff0c;其中…

nginx-链路追踪(trace)实现

一. 需求场景&#xff1a; 在日常运维工作中&#xff0c;会经常遇到在有多重调用链的场景下&#xff0c;如请求遇到非致命error时&#xff0c;在各环节的定位会非常麻烦&#xff0c;举个例子&#xff1a;比如说&#xff0c;在一个有多重调用链的服务环境下&#xff0c;一个请求…

c#使用SevenZipSharp实现压缩文件和目录

封装了一个类&#xff0c;方便使用SevenZipSharp&#xff0c;支持加入进度显示事件。 双重加密压缩工具范例&#xff1a; using SevenZip; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.…

MySQL和Hive中的行转列、列转行

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 MySQL1.行转列2.列转行 Hive1.行转列2.列转行(1)侧窗(2)union MySQL 1.行转列 把多行转成列。直接group&#xff0c;sum(if()) 2.列转行 Hive 1.行转列 select name,sum(if(kmshuxu…

快速上手:采用Let‘sEncrypt免费SSL证书配置网站Https (示例环境:Centos7.9+Nginx+Let‘sEncrypt)

1 关于Let’s Encrypt与Cerbot DNS验证 Let’s Encrypt 是一个提供 免费证书 的 认证机构。 Cerbot 是 Let’s Encrypt 提供的一个工具&#xff0c;用于自动化生成、验证和续订证书。 DNS验证是 Cerbot 支持的验证方式之一。相比 HTTP 验证或 TLS-ALPN 验证&#xff0c;DNS …

【Unity3D】Text文本文字掉落效果

相关技术&#xff1a;Text、TextMesh、Rigidbody&#xff08;刚体&#xff09;、BoxCollider&#xff08;碰撞体&#xff09;、TextGenerator、文本网格、文字网格 原理&#xff1a;使用UGUI Text获取其文字的每个字符网格坐标&#xff0c;转世界坐标生成对应的3D文本(TextMesh…

flutter 专题二十四 Flutter性能优化在携程酒店的实践

Flutter性能优化在携程酒店的实践 一 、前言 携程酒店业务使用Flutter技术开发的时间快接近两年&#xff0c;这期间有列表页、详情页、相册页等页面使用了Flutter技术栈进行了跨平台整合&#xff0c;大大提高了研发效率。在开发过程中&#xff0c;也遇到了一些性能相关问题和…

设计模式 行为型 命令模式(Command Pattern)与 常见技术框架应用 解析

命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它旨在将请求发送者和接收者解耦&#xff0c;通过将一个请求封装为一个对象&#xff0c;从而允许参数化客户端对象以进行不同的请求、排队请求或记录请求&#xff0c;并支持可撤销操作。 在软…

NodeLocal DNS 全攻略:从原理到应用实践

文章目录 一、NodeLocal DNS是什么&#xff1f;二、为什么使用NodeLocal DNS&#xff1f;三、工作原理架构图四、安装NodeLocal DNS五、在应用中使用NodeLocal DNSCache六、验证 一、NodeLocal DNS是什么&#xff1f; NodeLocal DNSCache 通过在集群节点上运行一个 DaemonSet …

jenkins入门12-- 权限管理

Jenkins的权限管理 由于jenkins默认的权限管理体系不支持用户组或角色的配置&#xff0c;因此需要安装第三发插件来支持角色的配置&#xff0c;我们使用Role-based Authorization Strategy 插件 只有项目读权限 只有某个项目执行权限

STM32-笔记34-4G遥控灯

4G接线 一、项目需求 服务器通过4G模块远程遥控开关灯。 二、项目实现 复制项目文件夹38-wifi控制风扇项目 重命名为39-4G遥控点灯 打开项目文件 加载文件 main.c #include "sys.h" #include "delay.h" #include "led.h" #include "ua…