読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

メモリを直接指定 #ikebin

UNIX

概要

レジスタ経由じゃなく直接指定でアクセスする。

作業としてはF#のコードに適切にデータを突っ込む。

リンク

7shi / ikebin / wiki / pdp11 / write-6 — Bitbucket

ソース

shigemk2/compiler · GitHub

逆アセンブラ

let aout = System.IO.File.ReadAllBytes "write-6.out"
let read16 (a:byte[]) b =
    (int a.[b]) ||| ((int a.[b+1]) <<< 8)
let tsize = read16 aout 2
let dsize = read16 aout 4
let mem = aout.[16 .. 16 + tsize + dsize - 1]
let mutable pc = 0
let show len dis =
    let words = [ for i in pc .. 2 .. pc + len - 1 -> sprintf "%04x" (read16 mem i) ]
    printfn "%04x: %-14s  %s" pc (String.concat " " words) dis
    pc <- pc + len
while pc < tsize do
    match read16 mem pc with
    | 0x1009 ->
        show 2 "mov r0, (r1)"
    | 0x10b1 ->
        show 4 (sprintf "mov r2, %x(r1)" (read16 mem (pc + 2)))
    | 0x15c0 ->
        show 4 (sprintf "mov $%x, r0" (read16 mem (pc + 2)))
    | 0x15c1 ->
        show 4 (sprintf "mov $%x, r1" (read16 mem (pc + 2)))
    | 0x15c2 ->
        show 4 (sprintf "mov $%x, r2" (read16 mem (pc + 2)))
    | 0x15c9 ->
        show 4 (sprintf "mov $%x, (r1)" (read16 mem (pc + 2)))
    | 0x95f1 ->
        show 6 (sprintf "movb $%x, %x(r1)" (read16 mem (pc + 2)) (read16 mem (pc + 4)))
    | 0x95c9 ->
        show 4 (sprintf "movb $%x, (r1)" (read16 mem (pc + 2)))
    | 0x9009 ->
        show 2 "mov r0, (r1)"
    | 0x9031 ->
        show 4 (sprintf "movb r0, %x(r1)" (read16 mem (pc + 2)))
    | 0x00c0 ->
        show 2 "swab r0"
    | 0x8901 ->
        show 2 "sys 1 ; exit"
    | 0x8904 ->
        show 2 "sys 4 ; write"
        show 2 "; arg"
        show 2 "; arg"
    | 0x15f7 ->
        show 6 (sprintf "mov $%x, %04x" (read16 mem (pc + 2)) (pc + 6 + read16 mem (pc + 4)))
    | 0x95f7 ->
        show 6 (sprintf "movb $%x, %04x" (read16 mem (pc + 2)) (pc + 6 + read16 mem (pc + 4)))
    | _ ->
        show 2 "???"

この逆アセの仕組みがイマイチよくわかっていない。

特に(pc + 6 + read16 mem (pc + 4)))。

うまいぐあいに足し算すればそのアドレスにいきつく。

00000000: 0701 4000 0600 0000 0c00 0000 0000 0000  ..@.............
00000010: c015 0100 0489 4000 0600 f715 4845 3000  ......@.....HE0.
00000020: c015 0100 0489 4000 0600 f715 4c4c 2200  ......@.....LL".
00000030: c015 0100 0489 4000 0600 f795 4f00 1400  ......@.....O...
00000040: c015 0100 0489 4000 0600 c015 0000 0189  ......@.........
00000050: 6865 6c6c 6f0a 0000 0000 0000 0400 0000  hello...........
00000060: 0000 0000 0500 0000 0000 0000 0400 0000  ................
00000070: 0000 0000 0500 0000 0000 0000 0400 0000  ................
00000080: 0000 0000 0500 0000 0000 0000 0400 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 6865 6c6c  ............hell
000000a0: 6f00 0000 0300 4000                      o.....@.

インタプリタ

let aout = System.IO.File.ReadAllBytes "write-6.out"
let read16 (a:byte[]) b =
    (int a.[b]) ||| ((int a.[b+1]) <<< 8)
let write16 (a:byte[]) b c =
    a.[b] <- byte ceil
    a.[b + 1] <- byte (c >>> 8)
let tsize = read16 aout 2
let dsize = read16 aout 4
let mem = aout.[16 .. 16 + tsize + dsize - 1]

let mutable r0, r1, r2, pc = 0, 0, 0, 0
while pc < tsize do
    match read16 mem pc with
    | 0x1009 ->
        write16 mem r1 r0
        pc <- pc + 2
    | 0x10b1 ->
        write16 mem (r1 + read16 mem (pc + 2)) r2
        pc <- pc + 4
    | 0x15b1 ->
        r0 <- read16 mem (pc + 2)
        pc <- pc + 4
    // mov
    | 0x15c0 ->
        r0 <- read16 mem (pc + 2)
        pc <- pc + 4
    // mov
    | 0x15c1 ->
        r1 <- read16 mem (pc + 2)
        pc <- pc + 4
    | 0x15c2 ->
        r2 <- read16 mem (pc + 2)
        pc <- pc + 4
    // mov
    | 0x15c9 ->
        write16 mem r1 (read16 mem (pc + 2))
        pc <- pc + 4
    | 0x15f1 ->
        write16 mem (r1 + read16 mem (pc + 4)) (read16 mem (pc + 2))
        pc <- pc + 6
    | 0x95c9 ->
        mem.[r1] <- mem.[pc + 2]
        pc <- pc + 4
    | 0x95f1 ->
        mem.[r1 + read16 mem (pc + 4)] <- mem.[pc + 2]
        pc <- pc + 6
    // sys 1 ; exit
    | 0x8901 ->
        exit r0
    // sys 4 ; write
    | 0x8904 ->
        let arg1 = read16 mem (pc + 2)
        let arg2 = read16 mem (pc + 4)
        let bytes = mem.[arg1 .. arg1 + arg2 - 1]
        printf "%s" (System.Text.Encoding.ASCII.GetString bytes)
        pc <- pc + 6
    | 0x00c0 ->
        r0 <- ((r0 &&& 0xff) <<< 8) ||| ((r0 &&& 0xff00) >>> 8)
        pc <- pc + 2
    | 0x9009 ->
        mem.[r1] <- byte r0
        pc <- pc + 2
    | 0x9031 ->
        mem.[r1 + read16 mem (pc + 2)] <- byte r0
        pc <- pc + 4
    | 0x15f7 ->
        write16 mem (pc + 6 + read16 mem (pc + 4)) (read16 mem (pc + 2))
        pc <- pc + 6
    | 0x95f7 ->
        mem.[r1 + pc + 6 + read16 mem (pc + 4)] <- mem.[pc + 2]
        pc <- pc + 6
    | w ->
        printfn "%04x: %04x ???" pc w
        exit 1