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

news2024/11/16 13:29:23

 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.coloradmin.cn/o/1397093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tui.calender日历创建、删除、编辑事件、自定义样式

全是坑🕳!全是坑🕳!全是坑🕳!能不用就不用! 官方文档:https://github.com/nhn/tui.calendar/blob/main/docs/en/apis/calendar.md 实例的一些方法,比如创建、删除、修改、…

【React】脚手架创建项目

文章目录 创建React项目目录结构分析了解PWA脚手架中的webpack 创建React项目 ◼ 创建React项目的命令如下: ​  注意:项目名称不能包含大写字母 ​  另外还有更多创建项目的方式,可以参考GitHub的readme 命令: create-rea…

Redis相关命令详解及其原理

Redis概念 Redis,英文全称是remote dictionary service,也就是远程字典服务。这是kv存储数据库。Redis,包括所有的数据库,都是请求-回应模式,通俗来说就是数据库不会主动地要给前台推送数据,只有前台发送了…

1026 程序运行时间 (15)

要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间。这个时间单位是 clock tick,即“时钟打点”。同时还有一个常数 CLK_TCK&…

使用zabbix-proxy进行分布式监控

目录 一、准备4台服务器 二、配置主从复制 1.准备环境 2.主机名解析 3.安装数据库 4.配置主库db1 5.配置从库db2 6.主从状态显示 三、db1,db2配置zabbix-agent 三、zabbix-server的配置 四、zabbix-proxy的配置 1.为您的平台安装和配置Zabbix-proxy a. …

勒索病毒:原理与防御

一、勒索病毒概述 勒索病毒,又称为Ransomware,是一种恶意软件,通过感染电脑系统、服务器或者手机等设备,使用户文件被加密,从而向用户索取赎金以解锁文件。近年来,勒索病毒已经成为网络安全领域的一大公害…

linux java 8安装

tar -zxf jdk-8u***.tar.gz -C /usr/loacl/ vim /etc/profile i 输入 export JAVA_HOME/usr/local/安装文件名 export PATH${JAVA_HOME}/bin:$PATH ESC :wq 保存退出 source /etc/profile 验证 java -version

【漏洞复现】上海真兰燃气收费系统信息泄露漏洞

Nx01 产品简介 上海真兰仪表科技股份有限公司,成立于2011年,真诺测量仪表成员,位于上海市,是一家以从事仪器仪表制造业为主的企业。 Nx02 漏洞描述 上海真兰仪表科技股份有限公司燃气收费系统存在信息泄露漏洞,log目录…

上海智慧岛大数据云计算中心项目正式封顶!

上海智慧岛大数据云计算中心封顶仪式现场 1月15日,云端股份在上海智慧岛大数据云计算中心举行封顶仪式。云之端网络(江苏)股份有限公司(以下称“云端股份”)总经理贡伟力先生,常务副总张靖先生等公司成员&…

BGP最通俗易懂的讲解——路由反射器

路由反射器 点赞关注,持续更新 路由反射器RR (Route Reflector) : 允许把从IBGP 对等体学到的路由反射到其他BGP对等体的BGP设备。客户机 (Client) : 与RR形成反射邻居关系的IBGP设备。在AS内部客户机只需要与RR建立邻居关系。非客户机 (Non-Client) …

CentOS 8.5 安装图解

特特特别的说明 CentOS发行版已经不再适合应用于生产环境,客观条件不得不用的话,优选7.9版本,8.5版本次之,最次6.10版本(比如说Oracle 11GR2就建议在6版本上部署)! 引导和开始安装 选择倒计时结…

如何使用Lychee结合内网穿透搭建私人图床网站并发布至公网远程访问

文章目录 1.前言2. Lychee网站搭建2.1. Lychee下载和安装2.2 Lychee网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4.公网访问测试5.结语 1.前言 图床作为图片集中存放的服务网站,可以看做是云存储的一部分,既可…

【计算机网络】HTTP协议以及简单的HTTP服务器实现

文章目录 一、HTTP协议1.认识URL2.urlencode和urldecode3.HTTP协议格式4.HTTP的方法5.HTTP的状态码6.HTTP常见Header7.重定向8.长连接9.会话保持10.基本工具 二、简单的HTTP服务器实现1.err.hpp2.log.hpp3.procotol.hpp4.Sock.hpp5.Util.hpp6.httpServer.hpp7.httpServer.cc8.总…

阿里云ECS使用docke搭建redis服务

目录 1.确保正确安装好docker 2.安装redis镜像 3.创建容器设置端口映射 1.确保正确安装好docker 安装教程: 阿里云ECS(CentOS镜像)安装docker-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135686614?spm1001.2014.3001.5501 2.安装redis镜像…

年龄性别预测1:年龄性别数据集说明(含下载地址)

年龄性别预测1:年龄性别数据集说明(含下载地址) 目录 年龄性别预测1:年龄性别数据集说明(含下载地址) 1.前言 2.MegaAge_Asian 3.MORPH 4.IMDB-WIKI 5.数据集下载 6.年龄性别预测和识别(Python/C/Android) 1.前言 本项目将实现年龄性别预测和识…

Java医药WMS进销存系统

技术架构: jdk8 IntelliJ IDEA maven Mysql5.7 有需要的可以私信我。 系统功能与介绍: 医药进销存系统,主要分两种角色:员工、客户。本系统具有进销存系统的通用性,可以修改为其它进销存系统,如家电进…

仿三方智能对话分析原始会话窗口

设计效果如下&#xff1a; 设计要求如下&#xff1a; 1、顶部播放条播放时&#xff0c;文字内容自动滚动。 监听audio事件timeupdate&#xff0c;只要播放器在播放就会触发该事件。每行文字有开始时间begin。判断当前时间&#xff08;currentTime&#xff09;<开始时间&am…

【分布式技术】Elastic Stack部署,实操logstash的过滤模块常用四大插件

目录 一、Elastic Stack&#xff0c;之前被称为ELK Stack 完成ELK与Filebeat对接 步骤一&#xff1a;安装nginx做测试 步骤二&#xff1a;完成filebeat二进制部署 步骤三&#xff1a;准备logstash的测试文件filebeat.conf 步骤四&#xff1a;完成实验测试 二、logstash拥有…

【REMB 】翻译:草案remb-03

REMB REMB消息 以及 绝对时间戳选项 在带宽估计中的使用 :an absolute-value timestamp option for use in bandwidth estimatoin. 接收方带宽估计的RTCP消息 REMB 这位大神翻译的更好。 RTCP message for Receiver Estimated Maximum Bitrate draft-alvestrand-rmcat-remb-03…

vite多页面打包学习(一)

一、前期准备 首先初始化两套独立的vue实例和相关生态&#xff08;多页面嘛&#xff09;&#xff0c;如下 我在src文件下创建了pages大文件夹&#xff0c;并初始化了两套页面分别为index和page1&#xff0c;每套页面都有自己单独的组件、路由、状态、入口等等&#xff0c;这里…