by shigemk2

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

8086 引き算 #ikebin

7shi / ikebin / wiki / 8086 / write-7 — Bitbucket

アセンブリ

! write(1, hello, 6);
mov ax, #1
int 7
.data1 4
.data2 hello, 6


! *(uint16_t *)hello -= 0x2020;
sub hello, #0x2020

! write(1, hello, 6);
mov ax, #1
int 7
.data1 4
.data2 hello, 6


! *(uint16_t *)(hello + 2) -= 0x2020;
sub hello + 2, #0x2020

! write(1, hello, 6);
mov ax, #1
int 7
.data1 4
.data2 hello, 6


! *(uint8_t *)(hello + 4) -= 0x20;
subb hello + 4, #0x20

! write(1, hello, 6);
mov ax, #1
int 7
.data1 4
.data2 hello, 6


! exit(0);
mov ax, #0
int 7
.data1 1


.sect .data
hello: .ascii "hello\n"

インタプリタ

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 = Array.zeroCreate<byte> 0x10000
mem.[0 .. tsize + dsize - 1] <- aout.[16 .. 16 + tsize + dsize - 1]
let mutable ax, bx, cx, ip = 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
    | 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

PDP-11にはなかったsub byteが…