ICS-lab4
代码下载
ICS-lab4%200064526ccef24a2aabe095e1eb2e217b/lab4.pdf
GitHub
https://github.com/echo-xiao9/SJTU-SE/tree/main/SE118_ICS:CSAPP%20(CMU%2015-213)/lab4
指令集合
程序测试指令
$./yat -s <ins_name> (e.g. ./yat -s rrmovq)
该命令将y64-ins-bin目录中的特定<ins_name>.bin文件设置为模拟器的输入文件,并通过与标准Y86-64模拟器(y64sim-base)生成的文件进行比较来检查模拟器生成的.sim文件。您可以看到结果(通过或失败)和特定指令的分数。
单步调试
$./yat -s <instruction> [max_steps](e.g. ./yat -s call 1)
这意味着程序将在1步后停止并打印结果。我们只检查最终输出(没有设置最大步骤),但是我们建议您使用这个选项来调试程序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QHBVYXHB-1617670724493)(ICS-lab4%200064526ccef24a2aabe095e1eb2e217b/2021-03-11_10.31.07.png)]
解题步骤
conditional code for y86
ZF,SF and OF (overflow)
见P201
OF (a<0 == b<0) && (t<0 ! = a<0)
对于≤ 可以列出所有情况如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-29HSPPOg-1617670724496)(ICS-lab4%200064526ccef24a2aabe095e1eb2e217b/IMG_7DABACAB2654-1.jpeg)]
reference:
https://github.com/Girafboy/ICS-AllLabs/blob/master/lab4/y64sim.c
踩过的坑
- 做compute alu的时候应该是 valB- valA 就因为这个找了半天
- 在pop和push 的时候一定要先写出如何改变的步骤,然后一步步实现。
- jmp需判断cond.
问题
regA = GET_REGA(codefun);
但是整个代码里面并没有实现,这是怎么get register的?
irrmov 里面为什么一定要判定cond_doit?
why this is STAT_ADR?
case I_MRMOVQ: /* 5:0 regB:regA imm */
if(!get_long_val(sim->m, valC+valB, &tmp)){
err_print("PC = 0x%lx, Invalid data address 0x%lx", sim->pc, valB + valC);
return STAT_ADR;
}
//why is STAT_ADR?
set_reg_val(sim->r, regA, tmp);
sim->pc = next_pc;
break;
why 两个set_reg_val不能互换?
case I_POPQ: /* B:0 regA:F */
//1. get tmp = m[%rsp] 2.r[%rsp] +=8 3. ra = tmp
valRsp = get_reg_val(sim->r,REG_RSP);
get_long_val(sim->m, get_reg_val(sim->r,REG_RSP), &tmp);
set_reg_val(sim->r, REG_RSP, get_reg_val(sim->r, REG_RSP)+8);
set_reg_val(sim->r, regA, tmp);
//why can‘t put between 2 lines?
sim->pc = next_pc;
break;
完成代码
/* Instruction set simulator for Y64 Architecture */
#include <stdio.h>
#include <stdlib.h>
#include "y64sim.h"
#define err_print(_s, _a...) \
fprintf(stdout, _s "\n", _a);
typedef enum
{
STAT_AOK,
STAT_HLT,
STAT_ADR,
STAT_INS
} stat_t;
char *stat_names[] = {
"AOK", "HLT", "ADR", "INS"};
char *stat_name(stat_t e)
{
if (e < STAT_AOK || e > STAT_INS)
return "Invalid Status";
return stat_names[e];
}
char *cc_names[8] = {
"Z=0 S=0 O=0",
"Z=0 S=0 O=1",
"Z=0 S=1 O=0",
"Z=0 S=1 O=1",
"Z=1 S=0 O=0",
"Z=1 S=0 O=1",
"Z=1 S=1 O=0",
"Z=1 S=1 O=1"};
char *cc_name(cc_t c)
{
int ci = c;
if (ci < 0 || ci > 7)
return "???????????";
else
return cc_names[c];
}
bool_t get_byte_val(mem_t *m, long_t addr, byte_t *dest)
{
if (addr < 0 || addr >= m->len)
return FALSE;
*dest = m->data[addr];
return TRUE;
}
bool_t get_long_val(mem_t *m, long_t addr, long_t *dest)
{
int i;
long_t val;
if (addr < 0 || addr + 8 > m->len)
return FALSE;
val = 0;
for (i = 0; i < 8; i++)
val = val | ((long_t)m->data[addr + i]) << (8 * i);
*dest = val;
return TRUE;
}
bool_t set_byte_val(mem_t *m, long_t addr, byte_t val)
{
if (addr < 0 || addr >= m->len)
return FALSE;
m->data[addr] = val;
return TRUE;
}
bool_t set_long_val(mem_t *m, long_t addr, long_t val)
{
int i;
if (addr < 0 || addr + 8 > m->len)
return FALSE;
for (i = 0; i < 8; i++)
{
m->data[addr + i] = val & 0xFF;
val >>= 8;
}
return TRUE;
}
mem_t *init_mem(int len)
{
mem_t *m = (mem_t *)malloc(sizeof(mem_t));
len = ((len + BLK_SIZE - 1) / BLK_SIZE) * BLK_SIZE;
m->len = len;
m->data = (byte_t *)calloc(len, 1);
return m;
}
void free_mem(mem_t *m)
{
free((void *)m->data);
free((void *)m);
}
mem_t *dup_mem(mem_t *oldm)
{
mem_t *newm = init_mem(oldm->len);
memcpy(newm->data, oldm->data, oldm->len);
return newm;
}
bool_t diff_mem(mem_t *oldm, mem_t *newm, FILE *outfile)
{
long_t pos;
int len = oldm->len;
bool_t diff = FALSE;
if (newm->len < len)
len = newm->len;
for (pos = 0; (!diff || outfile) && pos < len; pos += 8)
{
long_t ov = 0;
long_t nv = 0;
get_long_val(oldm, pos, &ov);
get_long_val(newm, pos, &nv);
if (nv != ov)
{
diff = TRUE;
if (outfile)
fprintf(outfile, "0x%.16lx:\t0x%.16lx\t0x%.16lx\n", pos, ov, nv);
}
}
return diff;
}
reg_t reg_table[REG_NONE] = {
{
"%rax", REG_RAX},
{
"%rcx", REG_RCX},
{
"%rdx", REG_RDX},
{
"%rbx", REG_RBX},
{
"%rsp", REG_RSP},
{
"%rbp", REG_RBP},
{
"%rsi", REG_RSI},
{
"%rdi", REG_RDI},
{
"%r8", REG_R8},
{
"%r9", REG_R9},
{
"%r10", REG_R10},
{
"%r11", REG_R11},
{
"%r12", REG_R12},
<