archlab


title: archlab实验报告:y86命令的使用
date: 2021-05-10 22:00:00
tags:

  • csapp report
  • assemble command
    comments: true
    categories:
  • assemble
  • y86

下载文件之后:

脑瓜子嗡嗡的,writeup看不懂,只能先去看看已有的实验报告,然后先做个总结——

先把里面的sim.tar解压了,然后进入目录之后make cleanmake会在里面的所有文件该生成的文件生成了。

part A

这个部分的文件全在misc文件夹。

意思大概是用y86指令集实现example.c文件里面的三个函数,那也太棒了呀,我最擅长手写汇编了,汇编它虽然码起来效率低,但是能直接对底层进行操作,想想都激动awa

要用到的指令:

./yis xxx.ys  
./yas xxx.yo

第一条可以理解为汇编,第二条可以理解为链接且运行。

sum_list

/* sum_list - Sum the elements of a linked list */
long sum_list(list_ptr ls)
{
    long val = 0;
    while (ls) {
		val += ls->val;
		ls = ls->next;
    }
    return val;
}

就是一个很朴素的链表求和,用循环实现。书上有例子的,那就直接把代码写下来吧,注释上写的挺清晰了。

	.pos 0#初始化
	irmovq stack,%rsp#初始化一个栈帧
	call main#执行主函数
	halt#结束
	.align 8#对齐
ele1:#链表头
	.quad 0x00a#链表值1
	.quad ele2#连接下一个表
ele2:
	.quad 0x0b0#链表值2
	.quad ele3#连接下一个表
ele3:
	.quad 0xc00#链表值3
	.quad 0#NULL
#This is main function
main:
	irmovq ele1,%rdi#传参
	call sum_list#调用函数
	ret 
sum_list:
        irmovq $0,%r14
        irmovq $0,%rax
L2:
        subq %r14,%rdi
        je L4#到了NULL跳转L4返回
        mrmovq (%rdi),%r13#取值
        addq %r13,%rax#加给ax寄存器
        mrmovq 8(%rdi),%rdi#下一个地址给%rdi
        jmp     L2
L4:
        ret
#stack starts here and grows to lower addresses
	.pos 0x200
stack:

运行结果:

archlab_PartA_1.png

while实现方式有多种,下面几种都可以,

L2:
	//循环块
	jnz L2
	ret
L2:
	jz L4
	//循环块
	jmp L2
L4:
	ret

……接下来读者自己想象吧

rsum_list

这一次也是要一个链表求和,只是函数需要递归。

那么这次我们稍微改一下,把跳转到L2改成重新call一次就好了呗,这里不过多解释了。

	.pos 0#初始化
	irmovq stack,%rsp#初始化一个栈帧
	call main#执行主函数
	halt#结束
	.align 8#对齐
ele1:#链表头
	.quad 0x00a#链表值1
	.quad ele2#连接下一个表
ele2:
	.quad 0x0b0#链表值2
	.quad ele3#连接下一个表
ele3:
	.quad 0xc00#链表值3
	.quad 0#NULL
#This is main function
main:
	irmovq ele1,%rdi#传参
	irmovq $0,%rax
	call sum_list#调用函数
	ret 
sum_list:
        irmovq $0,%r13
        subq %r13,%rdi
        je L4#到了NULL跳转L4返回
        mrmovq (%rdi),%r13#取值
        addq %r13,%rax#加给ax寄存器
        mrmovq 8(%rdi),%rdi#下一个地址给%rdi
        call sum_list#递归调用
L4:
        ret
#stack starts here and grows to lower addresses
	.pos 0x400
stack:

但是我这个做法在编译应该是不存在的,真正递归的话每次调用都应该用rax保存返回值的,但是我没有,因为我们是直接写汇编指令的,所以不必那么麻烦(其实我也不知道符不符合要求,反正能过的程序)

贴一个运行结果吧:

archlab_PartA_2.png

(PS:就感觉这个lab我写的挺水的,分析的东西比较少,可能还是我菜吧qwq)

copy_block

/* copy_block - Copy src to dest and return xor checksum of src */
long copy_block(long *src, long *dest, long len)
{
   
    long result = 0;
    while (len > 0) {
   
		long val = *src++;
		*dest++ = val;
		result ^= val;
		len--;
    }
    return result;
}

这第三个函数跟链表关系不大了,给出源地址和目的地址,源地址保存了一些值,要将源地址开始的len长度的数据拷贝到目的地址,并且把拷贝的值异或起来并且返回。首先len为循环次数没得跑,那么就先可以构建出它循环的基本框架

L2:
	//……
	irmovq $1,%r9
	subq %r9,%rdx
	jne L2
	ret

然后略去的内容无非就是赋值,异或,然后就完了…最后注意一下在main函数把三个参数传好,64位的程序前六个参数依次给rdi,rsi,rdx,rcx,r8,r9寄存器,那么main函数就应该是

main:
	irmovq src,%rdi
	irmovq dest,%rsi
	irmovq xxx,%rdx//这里的xxx自己写,写了多长的数据给多少数值
	call copy
	ret

那么自己再随便取一下destsrc汇编运行后就可以看到结果。

完整代码:

	.pos 0#初始化
	irmovq stack,%rsp#初始化一个栈帧
	call main#执行主函数
	halt#结束
	.align 8#对齐
src:
        .quad 0x00a
        .quad 0x0b0
        .quad 0xc00
dest:
        .quad 0x111
        .quad 0x222
        .quad 0x333
#This is main function
main:
        irmovq src,%rdi
        irmovq dest,%rsi
	irmovq $3,%rdx#argument len
	call copy
	ret 
co
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xi@0ji233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值