x86osdevlinker-flagswatcom80286

NASM+WCC+WLINK (OW 1.9): strange error addressing CONST data (wrong/even addressing)


I'm porting a tiny experimental 80286 kernel from pure assembler (NASM) to assembler+C (NASM+Open Watcom 1.9). Boot sector code loads the BIN kernel image at address 0x010000 and then jumps to that address.

The kernel code, after segs/stack initialization, prints a message: when addressing the message (char*), sometimes the first char is skipped: the print function (puts) begins to print from the 2nd char onwards. Other times, everything is OK: the string is printed starting from the 1st char.

Expected output:

Hello!

Actual output:

ello!

ASM startup code is:

start_:
    cli
    mov ax, 0x1000
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, 0xFFFE
    mov bp, sp

    call main_

_halt:
    hlt
    jmp _halt

C code is:

void puts( char* s )
{
    while( *s )
        putc( *s++ );
}

void main( void )
{
    puts( "Hello!" );
}

Then I have a simple BIOS helper function:

global _putc
_putc:
    push bp
    mov bp, sp

    push ax
    push bx

    mov ah, 0x0E
    mov al, [bp+4]
    mov bh, 0
    mov bl, 0
    int 0x10

    pop bx
    pop ax

    pop bp
    ret

NASM command lines are:

nasm -f obj os/src/start.asm -o os/obj/start.obj
nasm -f obj os/src/bios.asm -o os/obj/bios.obj

OW command lines are:

wcc -d0 -wx -we -ecc -ei -zpw -2 -od -zl -zld -zls -s os/src/main.c -fo=os/obj/main.obj
wlink @os.lnk

os.lnk:

FILE os/obj/start.obj
FILE os/obj/main.obj
FILE os/obj/bios.obj
FORMAT RAW BIN
NAME os/bin/os.bin
OPTION NODEFAULTLIBS
OPTION START=start_
OPTION MAP=os/lst/os.map
OPTION VERBOSE

I discovered that the behaviour depends on the lenght in bytes of the code (text): when everything works, just adding a single (or uneven number of) nop instruction somewhere in the code (C or ASM doesn't matter) produces the wrong behaviour. And vice versa. [nop takes only one byte]

Inspecting the assembler code (with WDISM or NDISASM), it seems that WLINK resolves the address of the string message always rounding to even addresses.

I'm a very newbie with OW, so it's highly probable that I'm missing something in the linker parameters; or in the segment specifiers of ASM and C code. Any help will be appreciated.


Solution

  • This is indeed a bug. It seems that it was addressed in OW 2.0 in February 2019, as reported in this post. I recompiled and linked with Open Watcom 2.0 and it worked as expected.