7shi / ikebin / wiki / 8086 / regs — Bitbucket
アセンブリ
mov ax, #0 mov bx, #0 mov cx, #0 mov dx, #0 mov sp, #0 mov bp, #0 mov si, #0 mov di, #0
逆アセンブラ
let aout = System.IO.File.ReadAllBytes "regs.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 = Array.zeroCreate<byte> 0x10000 mem.[0 .. tsize + dsize - 1] <- aout.[16 .. 16 + tsize + dsize - 1] let mutable ip = 0 let show len dis = let bin = [ for b in mem.[ip .. ip + len - 1] -> sprintf "%02x" b ] printfn "%04x: %-12s %s" ip (String.concat "" bin) dis ip <- ip + len while ip < tsize do match int mem.[ip], int mem.[ip + 1] with | 0xb8, _ -> show 3 (sprintf "mov ax, %04x" (read16 mem (ip + 1))) | 0xbb, _ -> show 3 (sprintf "mov bx, %04x" (read16 mem (ip + 1))) | 0xc7, 0x07 -> show 4 (sprintf "mov [bx], %04x" (read16 mem (ip + 2))) | 0xc7, 0x47 -> show 5 (sprintf "mov [bx+%x], %04x" mem.[ip + 2] (read16 mem (ip + 3))) | 0xc6, 0x07 -> show 3 (sprintf "mov byte [bx], %02x" mem.[ip + 2]) | 0xc6, 0x47 -> show 4 (sprintf "mov byte [bx+%x], %02x" mem.[ip + 2] mem.[ip + 3]) | 0x89, 0x07 -> show 2 (sprintf "mov [bx], ax") | 0x89, 0x4f -> show 3 (sprintf "mov [bx+%x], cx" mem.[ip + 2]) | 0xb9, _ -> show 3 (sprintf "mov cx, %04x" (read16 mem (ip + 1))) | 0x88, 0x07 -> show 2 (sprintf "mov [bx], al") | 0x88, 0x67 -> show 3 (sprintf "mov [bx+%x], ah" mem.[ip + 2]) | 0xb5, _ -> show 2 (sprintf "mov ch, %02x" mem.[ip + 1]) | 0xb1, _ -> show 2 (sprintf "mov cl, %02x" mem.[ip + 1]) | 0x89, 0x0f -> show 2 (sprintf "mov [bx], cx") | 0xc7, 0x06 -> show 6 (sprintf "mov [%04x], %04x" (read16 mem (ip + 2)) (read16 mem (ip + 4))) | 0xc6, 0x06 -> show 5 (sprintf "mov byte [%04x], %02x" (read16 mem (ip + 2)) mem.[ip + 4]) | 0x81, 0x2e -> show 6 (sprintf "sub [%04x], %04x" (read16 mem (ip + 2)) (read16 mem (ip + 4))) | 0x80, 0x2e -> show 5 (sprintf "sub byte[%04x], %02x" (read16 mem (ip + 2)) mem.[ip + 4]) | 0xba, _ -> show 3 (sprintf "mov dx, %04x" (read16 mem (ip + 1))) | 0xbc, _ -> show 3 (sprintf "mov sp, %04x" (read16 mem (ip + 1))) | 0xbd, _ -> show 3 (sprintf "mov bp, %04x" (read16 mem (ip + 1))) | 0xbe, _ -> show 3 (sprintf "mov si, %04x" (read16 mem (ip + 1))) | 0xbf, _ -> show 3 (sprintf "mov di, %04x" (read16 mem (ip + 1))) | 0xcd, 0x07 -> show 2 "int 7" match int mem.[ip] with | 1 -> show 1 "; exit" | 4 -> show 1 "; write" show 2 "; arg" show 2 "; arg" | _ -> show 1 "; ???" | 0xcd, n -> show 2 (sprintf "int %x" n) | _ -> show 1 "???"
インタプリタ
let aout = System.IO.File.ReadAllBytes "regs.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 = Array.zeroCreate<byte> 0x10000 mem.[0 .. tsize + dsize - 1] <- aout.[16 .. 16 + tsize + dsize - 1] let mutable ax, bx, cx, dx, sp, bp, si, di, ip = 0, 0, 0, 0, 0, 0, 0, 0, 0 while ip < tsize do match int mem.[ip], int mem.[ip + 1] with | 0xb8, _ -> ax <- read16 mem (ip + 1) ip <- ip + 3 | 0xbb, _ -> bx <- read16 mem (ip + 1) ip <- ip + 3 | 0xc7, 0x07 -> write16 mem bx (read16 mem (ip + 2)) ip <- ip + 4 | 0xc7, 0x47 -> write16 mem (bx + (int mem.[ip + 2])) (read16 mem (ip + 3)) ip <- ip + 5 | 0xc6, 0x07 -> mem.[bx] <- mem.[ip + 2] ip <- ip + 3 | 0xc6, 0x47 -> mem.[bx + (int mem.[ip + 2])] <- mem.[ip + 3] ip <- ip + 4 | 0x89, 0x07 -> write16 mem bx ax ip <- ip + 2 | 0x89, 0x4f -> write16 mem (bx + (int mem.[ip + 2])) cx ip <- ip + 3 | 0xb9, _ -> cx <- read16 mem (ip + 1) ip <- ip + 3 | 0x88, 0x07 -> mem.[bx] <- byte ax ip <- ip + 2 | 0x88, 0x67 -> mem.[bx + int mem.[ip + 2]] <- byte (ax >>> 8) ip <- ip + 3 | 0xb5, _ -> cx <- ((int mem.[ip + 1]) <<< 8) ||| (cx &&& 0xff) mem.[bx] <- byte ax ip <- ip + 2 | 0xb1, _ -> cx <- (cx &&& 0xff00) ||| (int mem.[ip + 1]) ip <- ip + 2 | 0x89, 0x0f -> write16 mem bx cx ip <- ip + 2 | 0xc7, 0x06 -> write16 mem (read16 mem (ip + 2)) (read16 mem (ip + 4)) ip <- ip + 6 | 0xc6, 0x06 -> mem.[read16 mem (ip + 2)] <- mem.[ip + 4] ip <- ip + 5 | 0x81, 0x2e -> let addr = bx + read16 mem (ip + 2) write16 mem addr ((read16 mem addr) - (read16 mem (ip + 4))) ip <- ip + 6 | 0x80, 0x2e -> let addr = read16 mem (ip + 2) mem.[bx + addr] <- mem.[addr] - mem.[ip + 4] ip <- ip + 5 | 0xba, _ -> dx <- read16 mem (ip + 1) ip <- ip + 3 | 0xbc, _ -> sp <- read16 mem (ip + 1) ip <- ip + 3 | 0xbd, _ -> bp <- read16 mem (ip + 1) ip <- ip + 3 | 0xbe, _ -> si <- read16 mem (ip + 1) ip <- ip + 3 | 0xbf, _ -> di <- read16 mem (ip + 1) ip <- ip + 3 | 0xcd, 0x07 -> match int mem.[ip + 2] with | 1 -> exit ax | 4 -> let arg1 = read16 mem (ip + 3) let arg2 = read16 mem (ip + 5) let bytes = mem.[arg1 .. arg1 + arg2 - 1] printf "%s" (System.Text.Encoding.ASCII.GetString bytes) ip <- ip + 7 | sc -> printfn "%04x: ??? syscall %d" ip sc exit 1 | 0xcd, n -> printfn "%04x: ??? int %x" ip n exit 1 | b, _ -> printfn "%04x: %02x ???" ip b exit 1
$ 7run regs.out stack overflow: 0000
でした。