概要
引き算により小文字から大文字へ変換。 メモリの中身を引き算を使うことで変更する。
逆アセンブラ
let aout = System.IO.File.ReadAllBytes "write-7.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)))
| 0xe5f7 ->
show 6 (sprintf "sub $%x, %04x" (read16 mem (pc + 2)) (pc + 6 + read16 mem (pc + 4)))
| _ ->
show 2 "???"
インタプリタ
let aout = System.IO.File.ReadAllBytes "write-7.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
// 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
| 0xe5f7 ->
let addr = pc + 6 + read16 mem (pc + 4)
write16 mem addr ((read16 mem addr) - (read16 mem (pc + 2)))
pc <- pc + 6
| w ->
printfn "%04x: %04x ???" pc w
exit 1
なお、僕のコードは変数をつかいわすれたやつ。
| 0xe5f7 ->
write16 mem (pc + 6 + read16 mem (pc + 4)) ((read16 mem (pc + 6 + read16 mem (pc + 4))) - (read16 mem (pc + 2)))
pc <- pc + 6