| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2174 人关注过本帖
标题:T.P版.模拟cpu什么意思阿。这题.....
只看楼主 加入收藏
zaixuexi
Rank: 12Rank: 12Rank: 12
来 自:上海
等 级:火箭侠
威 望:8
帖 子:858
专家分:3233
注 册:2010-12-1
收藏
得分:5 
r1r2r3的读法从D2~D0读

技术问题,请不要以短消息方式提问
2012-03-10 00:09
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
有道理。他的指令集是以位来标识寄存器,D3位用来标识源与目的。与我的思维习惯不太一样,不过都无所谓。
修改后的指令集,如果没有异议,就开始编码了。
程序代码:
r1 r2 r3

0001        复制操作
00010011    复制r3到r2
00010101    复制r3到r1
00010110    复制r2到r1
00011011    复制r2到r3
00011101    复制r1到r3
00011110    复制r1到r2

0010        加法
00100011    将r2与r3相加,结果存放在r2
00100101    将r1与r3相加,结果存放在r1
00100110    将r1与r2相加,结果存放在r1
00101011    将r3与r2相加,结果存放在r3
00101101    将r3与r1相加,结果存放在r3
00101110    将r2与r1相加,结果存放在r2

0011        减法
00110011    用r2减去r3,结果存放在r2
00110101    用r1减去r3,结果存放在r1
00110110    用r1减去r2,结果存放在r1
00111011    用r3减去r2,结果存放在r3
00111101    用r3减去r1,结果存放在r3
00111110    用r2减去r1,结果存放在r2

0100        移动到register
01000011    将r3中存放的地址的数据放到r2中
01000101    将r3中存放的地址的数据放到r1中
01000110    将r2中存放的地址的数据放到r1中
01001011    将r2中存放的地址的数据放到r3中
01001101    将r1中存放的地址的数据放到r3中
01001110    将r1中存放的地址的数据放到r2中
01000100 xxxxxxxx    数字X放到r1中
01000010 xxxxxxxx    数字X放到r2中
01000001 xxxxxxxx    数字X放到r3中

0101        移动到memory
01010011    将r2中存放的数据放到r3所指的内存地址中去
01010101    将r1中存放的数据放到r3所指的内存地址中去
01010110    将r1中存放的数据放到r2所指的内存地址中去
01011011    将r3中存放的数据放到r2所指的内存地址中去
01011101    将r3中存放的数据放到r1所指的内存地址中去
01011110    将r2中存放的数据放到r1所指的内存地址中去

0110        为零跳转
01100011    如果r2的值为零,则跳转到r3所指的代码处
01100101    如果r1的值为零,则跳转到r3所指的代码处
01100110    如果r1的值为零,则跳转到r2所指的代码处
01101011    如果r3的值为零,则跳转到r2所指的代码处
01101101    如果r3的值为零,则跳转到r1所指的代码处
01101110    如果r2的值为零,则跳转到r1所指的代码处

0111        不为零跳转
01110011    如果r2的值不为零,则跳转到r3所指的代码处
01110101    如果r1的值不为零,则跳转到r3所指的代码处
01110110    如果r1的值不为零,则跳转到r2所指的代码处
01111011    如果r3的值不为零,则跳转到r2所指的代码处
01111101    如果r3的值不为零,则跳转到r1所指的代码处
01111110    如果r2的值不为零,则跳转到r1所指的代码处

1000        打印
10000100    打印r1所指向的内存地址的数字
10000010    打印r2所指向的内存地址的数字
10000001    打印r3所指向的内存地址的数字
10001100    打印r1所指向的内存地址的字符串,字符串以0结尾
10001010    打印r2所指向的内存地址的字符串,字符串以0结尾
10001001    打印r3所指向的内存地址的字符串,字符串以0结尾

11110000    程序结束

重剑无锋,大巧不工
2012-03-10 09:27
zaixuexi
Rank: 12Rank: 12Rank: 12
来 自:上海
等 级:火箭侠
威 望:8
帖 子:858
专家分:3233
注 册:2010-12-1
收藏
得分:0 
没有异议

技术问题,请不要以短消息方式提问
2012-03-10 10:22
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
呵呵,看来成了你和我玩了。好吧,再讨论一件事情。

从楼主给的示例代码看,这个CPU的代码段和数据段是独立的,各自拥有256字节的空间。输入部分,先输入的是代码段数据,以程序结束标志结束,其后的为数据段数据。
(注:10000001 print r3->memory(1) 这句示例是估计是打错了。打印字符串应该是10001001)

有没有异议?

重剑无锋,大巧不工
2012-03-10 11:05
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
vm.rar (5.62 KB)
等不到讨论了。先做了一个虚拟机出来试试。
输入呢就按楼主的要求进行,直接回车则退出运行。程序正确结束将提示OVER,异常退出(如遇到未定义的指令)将提示ERROR,错误的输入也会这么提示。
其实直接输入二进制挺容易出错的。建议改成16进制。或者改成标记指令。





[ 本帖最后由 beyondyf 于 2012-3-10 12:19 编辑 ]

重剑无锋,大巧不工
2012-03-10 12:17
zaixuexi
Rank: 12Rank: 12Rank: 12
来 自:上海
等 级:火箭侠
威 望:8
帖 子:858
专家分:3233
注 册:2010-12-1
收藏
得分:0 
程序代码:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef uint8_t machine_size;
typedef machine_size m_size_t;
typedef uint32_t size_t;

#define _MOV               0x0001
#define _ADD               0x0010
#define _SUB               0x0011
#define _LEA               0x0101
#define _JZ                0x0110
#define _JNZ               0x0111
#define _DUMP              0x1000
#define _EXIT              0x11110000
#define SRC2DST            0x01
#define DST2SRC            0x00
#define UNIT_PER_BYTE      8
#define LOHALF(b)         (b & 0x0F)
#define HIHALF(b)         (b >> 4)
#define MAKEBYTE(l, h)    (((h << 4) & 0xF0) | (l & 0x0F))
#define MAKEWORD(a, b)    ((uint16_t)(((uint8_t)((uint32_t)(a) & 0xff)) |          \
                          ((uint16_t)((uint8_t)((uint32_t)(b) & 0xff))) << 8))
#define MAKELONG(a, b)    ((uint32_t)(((uint16_t)((uint32_t)(a) & 0xffff)) |       \
                          ((uint32_t)((uint32_t)((uint32_t)(b) & 0xffff))) << 16))
#define LOBYTE(w)         ((uint8_t)(w))
#define HIBYTE(w)         ((uint8_t)(((uint16_t)(w) >> 8) & 0xFF))
#define LOWORD(l)         ((uint16_t)(l))
#define HIWORD(l)         ((uint16_t)(((uint32_t)(l) >> 16) & 0xFFFF))
#define raise_bits(i, bits)    ((i) |= (bits))
#define _ARCH             intel
#define FAKE2REAL(index)  _ARCH[index]
#define _BV(bit)          (1 << (bit))
#define BV(i, bit)        ((i) << (bit))
#define BUG_ON(expr)      assert(!(expr))

static void bus_recv(void *, uint8_t*, size_t);
static void ins_decode(m_size_t);

#define STUB    0
#define DECLARE_CPU(name)              \
    struct cpu_context name = {        \
        STUB,                          \
        bus_recv,                      \
        ins_decode,                    \
        STUB,                          \
        STUB                           \
    };

#ifdef CONFIG_B2B_LMODE
#define B2B(out, in)                            \
    do {                                        \
        uint16_t i;                             \
        for (i = 0; i < UNIT_PER_BYTE; i++)     \
            raise_bits(out, _BV(7-i) & in[i]);  \
    } while (0);
#else
#define B2B(out, in)                            \
    do {                                        \
        uint16_t i, j;                          \
        for (i = 0, j = 0; i < UNIT_PER_BYTE; i+=2, j++)   \
            out[j] = MAKEBYTE(((in >> (7-i-1)) & 0x01),    \
                          ((in >> (7-i)) & 0x01));         \
    } while (0);
   
#endif
const uint16_t opcode[] = {
    _MOV, _ADD,
    _SUB, _LEA,
    _JZ, _JNZ,
    _DUMP, HIWORD(_EXIT), LOWORD(_EXIT)
};

const uint8_t *intel[] = {
    "MOV", "ADD",
    "SUB", "LEA",
    "JZ", "JNZ",
    "PRINT", "EXIT"
};

uint8_t *cmd_request;

#ifdef CONFIG_DEFAULT_CMD
#define SIGNHEX(n)    (0x##n)
#ifdef CONFIG_LSB_ENDIAN
#define HEX2BIN(hex)                 \
    BV((0x01 & (hex >> 28)), 7) |    \
    BV((0x01 & (hex >> 24)), 6) |    \
    BV((0x01 & (hex >> 20)), 5) |    \
    BV((0x01 & (hex >> 16)), 4) |    \
    BV((0x01 & (hex >> 12)), 3) |    \
    BV((0x01 & (hex >>  8)), 2) |    \
    BV((0x01 & (hex >>  4)), 1) |    \
    BV((0x01 & (hex >>  0)), 0)
#endif
uint8_t sysfifo[] = {
#if 0
    HEX2BIN(SIGNHEX(01000001)),
    HEX2BIN(SIGNHEX(00000011)),
    HEX2BIN(SIGNHEX(01000010)),
    HEX2BIN(SIGNHEX(00000010)),
    HEX2BIN(SIGNHEX(00100011)),
    HEX2BIN(SIGNHEX(01000100)),
    HEX2BIN(SIGNHEX(00000000)),
    HEX2BIN(SIGNHEX(01011110)),
    HEX2BIN(SIGNHEX(10000100)),
    HEX2BIN(SIGNHEX(11110000))
#else
    HEX2BIN(HIWORD(_EXIT)),
    HEX2BIN(LOWORD(_EXIT))
#endif   
};
#else
#endif

struct cpu_context {
    machine_size *pc;
    void(*recv)(void*, uint8_t*, size_t);
    void(*decode)(m_size_t);
    uint8_t *memmap;
    uint8_t priv[1];
};

DECLARE_CPU(cpu);

static void bus_recv(void *mem, uint8_t *fifo, size_t szfifo)
{
    /* BUG_ON(mem == 0); */
    memcpy(mem, fifo, szfifo);
}

static void __entry4_decode(m_size_t opcode)
{
    uint8_t op[4];
    B2B(op, opcode);
    switch (MAKELONG(MAKEWORD(op[3], op[2]), MAKEWORD(op[1], op[0]))) {
    case MAKELONG(_MOV, 0x0000):
        sprintf(cmd_request, "%s", FAKE2REAL(0));
    break;
    case MAKELONG(_ADD, 0x0000):
        sprintf(cmd_request, "%s", FAKE2REAL(1));
    break;
    case MAKELONG(_SUB, 0x0000):
        sprintf(cmd_request, "%s", FAKE2REAL(2));
    break;
    case MAKELONG(_DUMP, 0x0000):
        sprintf(cmd_request, "%s", FAKE2REAL(6));
    break;
    }
}

static void __entry8_decode(m_size_t opcode)
{
    uint8_t op[4];
    B2B(op, opcode);
    switch (MAKELONG(MAKEWORD(op[3], op[2]), MAKEWORD(op[1], op[0]))) {
    case _EXIT:
        sprintf(cmd_request, "%s", FAKE2REAL(7));
    break;
    }
}

static void ins_decode(m_size_t opcode)
{
    uint8_t op8;
    /* SAVE_REG(cpu.pc); */
#define READ_CACHE(idx)    *((m_size_t*)cpu.pc + 1)
    op8 = MAKEBYTE(LOHALF(READ_CACHE(idx)),LOHALF(opcode));
    __entry8_decode(op8);
    /* RESOTRE(cpu.pc); */
    /* cpu.pc += size_handled;
    /* __entry4_decode(opcode); */
}

void InitFakeCpu(struct cpu_context *cpu)
{
#define PAGE_SIZE    256
#define CPU_CACHE    2
#define PRIV_SIZE    CPU_CACHE + 64
    cpu->memmap = malloc(PAGE_SIZE + PRIV_SIZE);
    BUG_ON(cpu->memmap == 0);
    cpu->pc = cpu->memmap;
}

void FreeAll(void *obj)
{
    /* if (obj) free(obj); */
}

int main(int argc, char *argv[])
{
    /* if (argc < 2) do sth. */
    InitFakeCpu(&cpu);
    cmd_request = cpu.memmap + (PAGE_SIZE + PRIV_SIZE);
    (&cpu)->recv(cpu.memmap, sysfifo, sizeof(sysfifo));   
    (&cpu)->decode(*(m_size_t*)cpu.pc);
    fprintf(stdout, "req cmd analysis:%s\r\n", cmd_request);
    FreeAll(cpu.memmap);
    return 0;
}
一步步来

技术问题,请不要以短消息方式提问
2012-03-10 14:38
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:5 
你的代码好像还没建成,等你全弄完了咱们在交流心得。
对了,有没有试试我的程序?有没有查到什么BUG需要改进?或者建议?

重剑无锋,大巧不工
2012-03-10 14:52
chan_
Rank: 3Rank: 3
来 自:武汉
等 级:论坛游侠
帖 子:84
专家分:122
注 册:2012-2-29
收藏
得分:0 
收藏了
2012-03-10 22:07
你们都要疼我哦
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:火星
等 级:贵宾
威 望:49
帖 子:1296
专家分:2746
注 册:2008-7-13
收藏
得分:0 
2进制码可不能笔误呀

小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
2012-03-11 03:57
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
以下是引用clcqifeng在2012-3-9 17:10:03的发言:

。。。。。。。。。。
越听越迷糊。。
我想问。。。
.....你听 TonyDeng 扯,越听越迷糊也是应该的 。

你提的这个问题挺有意思,所以也吸引了不少人的兴趣。
但你一回来不知道是不是连自己的这个帖子都没看,就又去问了新帖,无视了大家的热情,确实很令人无语……
2012-03-12 23:24
快速回复:T.P版.模拟cpu什么意思阿。这题.....
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020600 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved