문제

하는 방법을 이해할 수석 binary 당 4 비트 가능한 경우.

예를 들어:저는 2 바이트 코드는 구문 분석할 필요가를 결정하는 명령을 사용하여

#{1NNN} 첫 번째는 4 비트 말하는 지,그리고 NNN 나타내는 메모리 위치(즉 #{1033} 말 점프하는 메모리 주소 #{0033}

그것은 쉬운 것을 이렇게 전체 바이트를,하지만 반을 가진 바이트:

parse #{1022} [#{10} {#22}] 

#{1} 유효하지 않습니다 binary!

그래서 지금까지 사용했던 거대한 스위치가 있는 문: #{1033} AND #{F000} = #{1000} 하기 위해 이러한 프로세스,그러나 궁금 더 성숙한 reboler 이 기능을 사용할 수 있습니다.

도움이 되었습니까?

해결책

이것은 오히려 큰 항목이지만,그것은 주소로 귀하의 요구에 보여줍 분석니다.

이것은 기본적으로 작동하지만,간단한 VM 사용하는 메모리 레이아웃을 설명합니다.

나는 설정을 간단한 블록 RAM 실제적인 프로그램이 실행되면 내가 사용하는 분석과 함께 에뮬레이터에 문법 규칙을...기본적으로 증가하는 주소 및 그때 이동하는 주소를 건너뛰는 NOP.

그중 일부는 불법 op 고 죽습니다.

REBOL [
    title:  "simple VM using Parse, from scratch, using no external libraries"
    author: "Maxim Olivier-Adlhoch"
    date:    2013-11-15
]

;----
; builds a bitset with all low-order bits of a byte set, 
; so only the high bits have any weight
;----
quaternary: func [value][
    bs: make bitset! 
    reduce [
        to-char (value * 16)
        '- 
        to-char ((value * 16) + 15)
    ]
]

;------
; get the 12 least significant bits of a 16 bit value
LSB-12: func [address [string! binary!] ][
    as-binary (address AND #{0FFF})
]

;------
i32-to-binary: func [
    n [integer!] 
    /rev
][
    n: load join "#{" [form to-hex to-integer n "}"]
    either rev [head reverse n][n]
]

;------
; load value at given address. (doesn't clear the opcode).
LVAL: func [addr [binary!]][
    to-integer copy/part at RAM ( (to-integer addr) + 1) 2
]


;------
; implement the opcodes which are executed by the CPU
JMP: func [addr][
    print ["jumping to " addr]
    continue: at RAM ((to-integer addr) + 1) ; 0 based address but 1 based indexing ;-)
]

INC: func [addr][
    print ["increment value at address: " addr]
    new-val: 1 + LVAL addr
    addr: 1 + to-integer addr
    bin-val: at (i32-to-binary new-val) 3
    change at RAM addr bin-val
]

DEC: func [addr][
    print ["decrement value at address: " addr]
]

NOP: func [addr][
    print "skipping Nop opcode"
]



;------
; build the bitsets to match op codes
op1: quaternary 1
op2: quaternary 2
op3: quaternary 3
op4: quaternary 4


;------
; build up our CPU emulator grammar
emulator: [ 
    some [
        [
            here:
            [ op1 (op: 'JMP)  | op2 (op: 'INC)  | op3 (op: 'DEC)  | op4 (op: 'NOP)] ; choose op code
            :here 

            copy addr 2 skip (addr: LSB-12 addr) ; get unary op data
            continue:
            (do reduce [op addr])
            :continue
        ]
        | 2 skip (
            print ["^/^/^/ERROR:  illegal opcode AT: " to-binary here " offset[" -1 + index? here "]"] ; graceful crash!
        )
    ]
]



;------
; generate a bit of binary RAM for our emulator/VM to run...

       0   2   4   6   8    ; note ... don't need comments, Rebol just skips them.
RAM: #{2002100540FF30015FFF}
RAM-blowup: { 2 002  1 005  4 0FF  3 001  5 FFF } ; just to make it easier to trace op & data


parse/all RAM emulator


print  "^/^/Yes that error is on purpose, I added the 5FFF bytes^/in the 'RAM' just to trigger it  :-)^/"

print "notice that it doesn't run the NOP (at address #0006), ^/since we used the JMP opcode to jump over it.^/"

print "also notice that the first instruction is an increment ^/for the address which is jumped (which is misaligned on 'boot')^/"

ask "press enter to continue"

출력은 다음과 같습니다:

increment value at address:  #{0002}
jumping to  #{0006}
decrement value at address:  #{0001}



ERROR:  illegal opcode AT:  #{5FFF}  offset[ 8 ]


Yes that error is on purpose, I added the 5FFF bytes
in the 'RAM' just to trigger it  :-)

notice that it doesn't run the NOP (at address #0006),
since we used the JMP opcode to jump over it.

also notice that the first instruction is an increment
for the address which is jumped (which is misaligned on 'boot')

press enter to continue
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top