明日行こうと思って昨日予約しようとしたら中止になっていた……
7shi / ikebin / wiki / pdp11 / write-4 — Bitbucket
わりと先週の復習もかねてる。
アセンブリ
数値を直接メモリに書き込むのが前回だったけど、今回は変数に数値を入れてそれからメモリに書き込む。
/ write(1, hello, 6); mov $1, r0 sys write hello 6 / r1 = hello; / r0 = 0x4548; / *(uint16_t *)r1 = r0; mov $hello, r1 mov $42510, r0 mov r0, (r1) / write(1, hello, 6); mov $1, r0 sys write hello 6 / r1 = hello; / r2 = 0x4c4c; / *(uint16_t *)(r1 + 2) = r2; mov $hello, r1 mov $46114, r2 mov r2, 2(r1) / write(1, hello, 6); mov $1, r0 sys write hello 6 / exit(0); mov $0, r0 sys exit .data hello: <hello\n>
逆アセンブラ
機械語から読みやすくするアレ
let aout = System.IO.File.ReadAllBytes "write-4.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))) | 0x8901 -> show 2 "sys 1 ; exit" | 0x8904 -> show 2 "sys 4 ; write" show 2 "; arg" show 2 "; arg" | _ -> show 2 "???"
インタプリタ
let aout = System.IO.File.ReadAllBytes "write-4.out" let read16 (a:byte[]) b = (int a.[b]) ||| ((int a.[b+1]) <<< 8) let write16 (a:byte[]) b c = a.[b] <- byte c 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 | 0x15c0 -> r0 <- read16 mem (pc + 2) pc <- pc + 4 | 0x15c1 -> r1 <- read16 mem (pc + 2) pc <- pc + 4 | 0x15c2 -> r2 <- read16 mem (pc + 2) pc <- pc + 4 | 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 | 0x8901 -> exit r0 | 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 | w -> printfn "%04x: %04x ???" pc w exit 1