Architecture Lab:part A 【实现sum_list/rsum_list/copy_block/熟悉Y86-64指令】

 Architecture Lab 对应CS:APP的Chap 4——处理器体系结构。Part A要实现三个函数,分别为sum_list/rsum_list/copy_block。建议先得到x86-64指令,然后再转换为Y86-64指令。

准备工作

在misc目录下,键入以下命令用来生成汇编代码。命令执行完毕后会生成examples.o。

gcc -S examples.c

sum_list的Y86-64实现

在examples.o中找到第一个要实现的函数sum_list,如下

sum_list:
.LFB0:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movq	%rdi, -24(%rbp)
	movq	$0, -8(%rbp)
	jmp	.L2
.L3:
	movq	-24(%rbp), %rax
	movq	(%rax), %rax
	addq	%rax, -8(%rbp)
	movq	-24(%rbp), %rax
	movq	8(%rax), %rax
	movq	%rax, -24(%rbp)
.L2:
	cmpq	$0, -24(%rbp)
	jne	.L3
	movq	-8(%rbp), %rax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc

可见,这个代码是将局部变量存在栈帧上,而书上的x86代码并不是这么复杂,而是直接把值存在某寄存器中,进行加减操作。那么我们也来做一些等价转换,转换后的结果如下代码:

sum_list:
.LFB0:
	movq	$0, %rax
	jmp	.L2
.L3:
	addq	(%rdi), %rax
	movq	8(%rdi), %rdi
.L2:
	cmpq	$0, %rdi
	jne	.L3
	ret

然后根据Y86-64的规则,进行改写。

sum_list:
.LFB0:
    movq    $0, %rax -> irmovq $0, %rax
    jmp    .L2
.L3:
    addq    (%rdi), %rax -> mrmovq (%rdi), %r8      addq %r8, %rax
    movq    8(%rdi), %rdi ->mrmovq 8(%rdi), %rdi
.L2:
    cmpq    $0, %rdi ->andq %rdi, %rdi
    jne    .L3
    ret

即为

sum_list:
.LFB0:
    irmovq $0, %rax
    jmp    .L2
.L3:
    mrmovq    (%rdi), %r8
    addq      %r8, %rax
    mrmovq    8(%rdi), %rdi
.L2:
    andq %rdi, %rdi
    jne    .L3
    ret

 这只是一个函数,现需要把它写为完整的程序。根据书上page 252的代码4-7,补上main函数、调用main函数的语段、数据段即可。如下:

	.pos 0
	irmovq stack,%rsp
	call main
	halt

# 这是archlab.pdf中给出的测试样例
	.align 8
ele1:
	.quad 0x00a
	.quad ele2
ele2:
	.quad 0x0b0
	.quad ele3
ele3:
	.quad 0xc00
	.quad 0
	
	
main:
	irmovq	ele1, %rdi
	call sum_list
	ret
	
sum_list:
LFB0:
	irmovq	$0, %rax
	jmp	L2
L3:
	mrmovq	(%rdi), %r8
	addq	%r8, %rax
	mrmovq	8(%rdi), %rdi
L2:
	andq	%rdi, %rdi
	jne	L3
	ret
	
	.pos 0x200
stack:

用yas得到.yo文件,再用yis运行.yo文件,得到各个寄存器运行后的值,如下。 

sum_list函数完成。 

rsum_list的Y86-64实现

在examples.o中找到第二个要实现的函数rsum_list,如下:

rsum_list:
.LFB1:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$32, %rsp
	movq	%rdi, -24(%rbp)
	cmpq	$0, -24(%rbp)
	jne	.L6
	movl	$0, %eax
	jmp	.L7
.L6:
	movq	-24(%rbp), %rax
	movq	(%rax), %rax
	movq	%rax, -16(%rbp)
	movq	-24(%rbp), %rax
	movq	8(%rax), %rax
	movq	%rax, %rdi
	call	rsum_list
	movq	%rax, -8(%rbp)
	movq	-16(%rbp), %rdx
	movq	-8(%rbp), %rax
	addq	%rdx, %rax
.L7:
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc

同样,递归产生的n个栈帧中存了两个参数和求得的和。由于是递归,是否寄存器不可简化?

答案是可以简化的,栈帧上只存求得的和,不存两个参数。 

rsum_list:
.LFB1:
	cmpq	$0, %rdi
	jne	.L6
	movl	$0, %eax
	jmp	.L7
.L6:
	movq	(%rdi), %rax
    push    %rax
	movq	8(%rdi), %rdi
	call	rsum_list
    pop     %r8
	addq	%r8, %rax
.L7:
	ret

 把这个简化之后的x86-64代码转换为Y86-64

rsum_list:
.LFB1:
	andq %rdi, %rdi
	jne	.L6
	irmovq	$0, %rax
	jmp	.L7
.L6:
	mrmovq	(%rdi), %rax
    push    %rax
	mrmovq	8(%rdi), %rdi
	call	rsum_list
    pop     %r8
	addq	%r8, %rax
.L7:
	ret

放到刚刚写的框架中即可。

copy_block的Y86-64实现

在examples.o中找到第三个要实现的函数copy_block,如下:

copy_block:
.LFB2:
	.cfi_startproc
	endbr64
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movq	%rdi, -24(%rbp)
	movq	%rsi, -32(%rbp)
	movq	%rdx, -40(%rbp)
	movq	$0, -16(%rbp)
	jmp	.L9
.L10:
	movq	-24(%rbp), %rax
	leaq	8(%rax), %rdx
	movq	%rdx, -24(%rbp)
	movq	(%rax), %rax
	movq	%rax, -8(%rbp)
	movq	-32(%rbp), %rax
	leaq	8(%rax), %rdx
	movq	%rdx, -32(%rbp)
	movq	-8(%rbp), %rdx
	movq	%rdx, (%rax)
	movq	-8(%rbp), %rax
	xorq	%rax, -16(%rbp)
	subq	$1, -40(%rbp)
.L9:
	cmpq	$0, -40(%rbp)
	jg	.L10
	movq	-16(%rbp), %rax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc

简化代码

copy_block:
.LFB2:
	movq	$0, %rax
	jmp	.L9
.L10:
	movq	(%rdi), %r8
	leaq	8(%rdi), %rdi
	movq	%r8, (%rsi)
	leaq	8(%rsi), %rsi
	xorq	%r8, %rax
	subq	$1, %rdx
.L9:
	cmpq	$0, %rdx
	jg	.L10
	ret

改为Y86-64代码

copy_block:
.LFB2:
	irmovq	$1, %r9 	# const value
	irmovq	$8, %r10 	# const value
	irmovq	$0, %rax
	jmp	.L9
.L10:
	mrmovq	(%rdi), %r8
	addq 	%r10, %rdi
	rmmovq	%r8, (%rsi)
	addq 	%r10, %rsi
	xorq	%r8, %rax
	subq	%r9, %rdx
.L9:
	andq	%rdx, %rdx
	jg	.L10
	ret

新建copy_block.ys

	.pos 0
	irmovq stack,%rsp
	call main
	halt
	
	.align 8
# Source block
src:
	.quad 0x00a
	.quad 0x0b0
	.quad 0xc00
	
# Destination block
dest:
	.quad 0x111
	.quad 0x222
	.quad 0x333


main:
	irmovq	src, %rdi
	irmovq	dest, %rsi
	irmovq	$3, %rdx
	call copy_block
	ret

copy_block:
LFB2:
	irmovq	$1, %r9 	# const value
	irmovq	$8, %r10 	# const value
	irmovq	$0, %rax
	jmp	L9
L10:
	mrmovq	(%rdi), %r8
	addq 	%r10, %rdi
	rmmovq	%r8, (%rsi)
	addq 	%r10, %rsi
	xorq	%r8, %rax
	subq	%r9, %rdx
L9:
	andq	%rdx, %rdx
	jg	L10
	ret
	
	.pos 0x500
stack:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux快速部署文件服务器

参考文档: Linux命令之nohup详解 - 掘金 【Linux】ps -ef|grep详解-CSDN博客 有个简单想法,我的一些文件放在机器某个目录下面,可以简单提供团队内部人员浏览和下载功能,节约时间,用最简单方法实现。 注:…

MyBatisPlus学习笔记五-插件功能

0、插件功能 MyBatisPlus提供的内置拦截器有下面这些 1、分页插件 2、通用分页实体 3、通用分页实体-强化 需求: 在PageQuery中定义方法,将PageQuery对象转为MyBatisPlus中的Page对象在PageDTO中定义方法,将MyBatisPlus中的Page结果转为Page…

mysql原理--事务的隔离级别与 MVCC

1.事前准备 为了故事的顺利发展,我们需要创建一个表: CREATE TABLE hero (number INT,name VARCHAR(100),country varchar(100),PRIMARY KEY (number) ) EngineInnoDB CHARSETutf8;然后向这个表里插入一条数据:INSERT INTO hero VALUES(1, 刘…

想做一名严肃的伦敦金投资者?那请做好以下这两个准备

在伦敦金市场中,如果投资者想成为一名脚踏实地的投资者,首先要在心态上、思想上对自己进行改造,起码接受自己是严肃投资者的身份,然后再完成下面我们提出的这两种准备。 选择一种自己喜欢的交易策略。既然要成为一名严肃的投资者&…

栈、队列专题

文章目录 栈栈的概述栈的实现栈在函数调用中的应用栈在表达式求值中的应用逆波兰表达式求值 栈在括号匹配中的应用有效的括号最长的有效括号删除字符串中的所有相邻重复项 如何获取栈内最小元素呢如何实现浏览器的前进和后退 队列队列的定义队列的实现循环队列队列的应用队列在…

Pytorch实战——3、数据加载与处理

🍅 写在前面 👨‍🎓 博主介绍:大家好,这里是hyk写算法了吗,一枚致力于学习算法和人工智能领域的小菜鸟。 🔎个人主页:主页链接(欢迎各位大佬光临指导) ⭐️近…

【音视频原理】图像相关概念 ③ ( RGB 色彩简介 | RGB 排列 | YUV 色彩简介 | YUV 编码好处 )

文章目录 一、RGB 色彩1、RGB 色彩简介2、RGB 排列 二、YUV 色彩1、YUV 色彩简介2、YUV 编码好处 一、RGB 色彩 1、RGB 色彩简介 RGB 是 计算机 中的 颜色编码方法 , 红 ( R ) / 绿 ( G ) / 蓝 ( B ) 三个颜色通道 可以设置不同的值 , 每个 通道 的 颜色值都可以取值 0 ~ 255 ,…

Python智能挖掘数据新秘器

大家好,本次分享一款在数据探索中表现出色的工具—Python Lux ,通过自动化可视化和数据分析过程,使得数据探索变得更加快捷方便。 Lux的使用方法非常简单,只需在Jupyter notebook中输入dataframe,Lux就会智能推荐一组基…

Java项目:10 Springboot的电商书城管理系统

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 该系统分为前台展示和后台管理两大模块,前台主要是为消费者服务。该子系统实现了注册,登录,以及从浏览、下单到支付…

第三讲_ArkTS的初识

ArkTS的初识 1. ArkTS的基本组成2. ArkTS自定义组件 1. ArkTS的基本组成 装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。自定义组件:可复用的UI单元,可组合其他组件,图示中Component装饰的struct Hello…

Halcon 一维测量

文章目录 算子矩形算子弧形算子移动到新的参考点 Halcon 案例测量保险丝的宽度(边缘对测量)使用助手进行测量 halcon 案例获取芯片引脚的个数平均宽度距离,连续两个边缘的距离(measure_pos )halcon 定位测量Halcon 测量…

C#,水仙花数(Narcissistic number)的计算方法及源代码

一、水仙花数(Narcissistic number) 水仙花数(Narcissistic number)也被称为:超完全数字不变数(pluperfect digital invariant, PPDI)、自恋数、自幂数、阿姆斯壮数或阿姆斯特朗数(A…

B站提示:“当前浏览器版本较低……”可行的解决方案(edge浏览器)

文章目录 问题研究和分析使用User-Agent Switcher for Chrome插件的解决方法使用userAgent switcher的解决方法 问题研究和分析 问题:使用最新版浏览器访问B站,首页总是有一条横幅提示:当前浏览器版本较低,为保证您的使用体验&am…

vscode设置terminal的最大行数

今天跑代码出现一个问题,就是整个程序跑完,整个程序的输出信息过多,最开始输出的信息已经被vscode的缓存冲掉了,只能看到最后的一部分,具体的原因是vscode的terminal默认只能保存1000行的信息,所以如果想保…

智慧仓储物流远程监控方案分析

智慧仓储物流远程监控方案分析 随着物联网、大数据、云计算等技术的快速发展,智慧仓储物流逐渐成为现代物流发展的重要方向。远程监控作为智慧仓储物流的重要组成部分,可以有效提高仓储物流的效率、准确性和安全性。 一、智慧仓储物流远程监控方案概述 …

llvm pass

pass们组合在一起,处理IR 而最后的目标代码生成阶段,会生成另一种MIR(Machine IR) PassManager管理这些pass pass处理IR之后会改变分析的情况,这些关于IR的信息由 AnalysisManager处理 1、pass (1&…

在线多端口排课教务管理工具:教育机构管理的得力助手

在现代教育中,教务管理是一个复杂而重要的任务。为了简化这一过程,许多在线教务管理工具应运而生。今天,我将向大家介绍一款名为乔拓云的在线多端口排课教务管理工具。 首先,乔拓云是一个功能强大的教务管理系统。它不仅提供了小程…

Python创建线程

Python 提供了 _thread 和 threading 两个模块来支持多线程,其中 _thread 提供低级别的、原始的线程支持,以及一个简单的锁,正如它的名字所暗示的,一般编程不建议使用 thread 模块;而 threading 模块则提供了功能丰富的…

使用C#操作文件:一个实际案例——替换文件中的IP地址

标题: 使用C#操作文件:一个实际案例——替换文件中的IP地址 介绍: 欢迎阅读我的最新博客!今天,我们将探讨如何使用C#来处理一个实际的编程挑战:读取一个配置文件并替换其中的IP地址。这是一个非常常见的…
最新文章