I'm writing a hello-world program for Xenix 86 in NASM. See the full source code. If I only put this to the code segment, then it fails with segfault (Memory fault) on Xenix 286:

        mov ax, 4  ; $SYSCALL.write.
        mov bx, 1  ; STDOUT_FILENO.
        mov cx, msg
        mov si, msg.end-msg
        int 5

        mov ax, 1  ; $SYSCALL.exit.
        xor bx, bx  ; EXIT_SUCCESS.
        int 5
        ; Not reached.

However, if I replace the two instances of int 5 with call 0x17, then it works. The code at offset 0x17 is also part of my program (see it in the full source code above), it does an int 5, a jmp, and then a ret. This is unusual: int 5 doesn't work directly, but it works if it's called from the first 0x80 byte of the code. I suspect that the reason for this behavior is that after Xenix 86 or 286 loads the program, it changes the first 0x80 bytes of the code, so the int 5 is actually some other instruction.

What exactly is the behavior of the first 0x80 code bytes on Xenix 86, and where is it documented?

I've managed to make my hello-world program work even without fully understanding the ABI by disassembling the /bin/echo program in Xenix 86 2.1.3 (and also manually parsing its header by looking at /usr/include/sys/a.out.h), and then copying the first 0x80 bytes of code in there (from file offset 0xa0) to my program.


You must log in to answer this question.

Browse other questions tagged .