Greetings everyone
Today I was designing builds for my program in the assembler hoping to get a verification for this subject. Right now I have a certain configuration file where my code runs seemingly well however if I try to change the address of one of the files I lose functionality(especially obvious as this file is a graphic component). I had used to use NASM's ORG instruction for most programs but I use ld for my configurations whenever the file is larger than 512b (this was the subject of my previous post).
To surmize I would like to share the design here as an illustration for the purpose of review. The main program is just a function of ordinary NASM and x86 instructions modeled for the 1 MB BIOS function platform and outlined simply by the files and figure below. One other quick observation to clarify is that most of the stage files correspond to the paths shown.
Boot => Stage1.asm (16-32 gate function) => Stage2.asm (BIOS_16 code fitting) =>Stage3.asm (BIOS graphics functions)
+(secondary path test) test2.asm
The question is essentially a product of changing the aforementioned path by any means. In the build file you can observe that BOTH ld and ORG instructions however the fit for stage3 graphics is tight as is so I'm trying to move this to earlier segments that 0xA000. If I change this to anywhere other than that segment (0x9000,0x8000) I just get a blank screen. Naturally speaking I know I have to change a module in each file as outlined below.
Disk_Read(boot.asm)=>Jump_From_Gate(Stage1.asm)=>Jump_Into_BIOS16_Segment(Stage2.asm)=>Stage3_Addressment
From what I understand if it runs for one address it should run for any address but it doesn't. I know that there's a difference between the two file types but the inferences here look kinda conspicuous as is. That's why I was very curious and hoping here if anyone else understood what happened.I'm posting the full source and I'd be really happy and available to correspond any further. One more thing was I had to add stage3 attach stage3 due to file constraints. Cheers!
boot.asm
; ReTimerOS
; Copyright (C) 2022,2023 Christopher Hoy
;
; This file is part of ReTimerOS
; ReTimerOS is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program. If not, see <https://www.gnu.org/licenses/>.
[org 0x7c00]
[bits 16]
mov cx,0
mov ds,cx
mov es,cx
cld
mov si,msgString
call kprint
mov cx,0x1000
mov es,cx
mov bx,0x0000_0000
;mov bx,0x0000_D000
mov cl,5
mov bx,msgString
;mov bx,0x0000_D000
mov bx,0x0000_0000
mov cl,5
mov al,1
call read_section
;mov cx,0xD00
mov cx,0x1000
mov es,cx
mov bx,0
;mov al,1
mov cl,5
mov al,1
call read_section
mov cx,0
mov ds,cx
mov es,cx
;mov bx,0x0000_9000
mov bx,0x0000_A000
mov cl,4
mov bx,msgString
;mov bx,0x0000_9000
mov bx,0x0000_A000
mov cl,4
mov al,0x30
call read_section
;mov cx,0x900
mov cx,0xA00
mov es,cx
mov bx,0
;mov al,1
mov cl,4
;mov bx,0x0000_8000
mov al,0x30
call read_section
mov bx,0x0000_8000
mov cl,3
mov bx,msgString
mov bx,0x0000_8000
mov cl,3
mov al,1
call read_section
mov cx,0x800
mov es,cx
mov bx,0
mov cl,3
;mov bx,0x0000_8000
mov al,1
call read_section
mov bx,0x0000_7e00
mov bx,0x0000_7e00
mov cl,2
mov bx,msgString
mov bx,0x0000_7e00
mov cl,2
mov al,1
call read_section
mov cx,0x7e0
mov es,cx
mov bx,0
mov cl,2
;mov bx,0x0000_8000
mov al,1
call read_section
mov bx,0x0000_7e00
;mov cx,0
;mov es,cx
pusha
jmp 0x7e00
;jmp 0x9200
;jmp 0xD000
jmp $
kprint:
cld
mov ah,0x0E
kstring:
lodsb
int 0x10
cmp al,0x00
jnz kstring
ret
read_section:
mov ah,0x02
; mov al,1
mov ch,0
mov dh,0
int 0x13
jc .disk_check
ret
.disk_check:
mov si,checkString
call kprint
jmp $
.done:
ret
;section .data
align 4
BOOT_DRIVE: db 0
msgString: db 'Game platform premier',10,13,0
checkString: db 'Section did not load',10,13,0
checkString2: db 'disk complete',10,13,0
times 510 -($-$$) db 0
dw 0xaa55
stage1.asm
;%define REBASE_ADDRESS(A) (0x7E00 + ((A) - protectedGate1))
%define BUILD_GDT_DESC(bounds,base,access,flags) \
((( base & 0x00FFFFFF) << 16) | \
(( base & 0xFF000000) << 32) | \
( bounds & 0x0000FFFF) | \
(( bounds & 0x000F0000) << 32) | \
(( access & 0xFF) << 40) | \
(( flags & 0x0F) << 52))
;[ORG 0x7E00]
[BITS 16]
;section .text
protectedGate1:
;mov bx,0x0000_9000
mov si,String
call kprint
cld
cli
in al,0x92
or al,2
out 0x92,al
lgdt[gdt32Ptr]
lidt[IdtPipe]
mov eax, cr0
or eax,1
mov cr0, eax
; mov [saved_segment],ds
; jmp code32_post:REBASE_ADDRESS(__protected_mode_32)
jmp code32_post:__protected_mode_32
; jmp $
; jmp code32_post:__protected_mode_32
kprint:
cld
mov ah,0x0E
kstring:
lodsb
int 0x10
cmp al,0x00
jnz kstring
ret
;section .text
[bits 32]
; 32 bit protected mode
__protected_mode_32:use32
; mov ax, 0x10
mov ax,data32_post
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; mov ss, ax
; restate cr3
mov cr3, ebx
; restate esp
mov esp, edx
mov cx,[gate_voucher]
cmp word [gate_voucher],0
jnz loopcheck
mov word [gate_voucher],1
jmp BIOS32_PREP
loopcheck:
hlt
jmp loopcheck
; jmp 0x8000
BIOS32_PREP:use32
pusha
;pushf
; save current esp to edx
mov edx, esp
; jumping to 16 bit protected mode
; disable interrupts
cli
; clear cr3 by saving cr3 data in ebx register
xor ecx, ecx
mov ebx, cr3
mov cr3, ecx
jmp code16_post:__protected_mode_16
[bits 16]
; 16 bit protected mode
__protected_mode_16:use16
; jumping to 16 bit real mode
xor eax,eax
xor ecx,ecx
; mov ax, 0x38
mov cx,data16_post
; mov ax,0
mov ds, cx
mov es, cx
mov fs, cx
mov gs, cx
mov ss, cx
; turn off protected mode
; set bit 0 to 0
mov eax, cr0
and al, ~0x01
mov cr0, eax
; jmp 0x8000
jmp 0xA000
;section .data
String: db 'platform 2',10,13,0
checkString: db 'check',10,13,0
gdt32:
dq BUILD_GDT_DESC(0,0,0,0)
gdt32code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1100b)
gdt32data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1100b)
gdt16code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1000b)
gdt16data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1000b)
.stub1:
code32_post: equ gdt32code -gdt32
data32_post: equ gdt32data -gdt32
;.stub:
code16_post: equ gdt16code -gdt32
data16_post: equ gdt16data -gdt32
; tss32_post: equ gdt32tss -gdt32
gdt32Len: equ $-gdt32
gdt32Ptr: dw gdt32Len-1
dd gdt32
save_cr0 dd 0
save_cr3 dd 0
saved_segment resd 0
gate_voucher dw 0
saved_stack resw 0
IdtPipe:
dw 0x03ff
dd 0
times 512-($-$$) db 0
;%include 'gdt.inc'
stage2.asm
stage3.asm ( pretty lengthy from the graphic methods and had to attach seperately instead)
stage4.asm (resides as a proof of concept)
[org 0x10000]
[BITS 16]
_prep_module2:
_vm_module:
sub dword [_vidmem_ptr],_VIDEO_TEXT_ADDR
mov si,_vm_str
call _printstr_task
_loopcheck: jmp $
_vm_str: db 'long test 1',0
_printstr_task:
push cx
mov bp,0b800h
mov es,bp
mov bp,[_vidmem_ptr]
_prep:
mov cx,0
mov es,cx
mov ax,_ROWS
mov bx,es:0x044a
mul bx
add ax,_COLS1
; shl ax,1
mov bp,ax
add bp,[_vidmem_ptr]
;check even and odd placements
; wizard tactics 1.7
add bp,0x690
; wizard tactics 1.8
; times 140 inc bp
; wizard tactics 1.9
times 20 inc bp
;boundary
;check even and odd placements
mov cx,0b800H
mov es,cx
mov ch,_COLOR_ATTR_BSC
jmp _gettext
_output:
pop ax
mov dx,ax
mov es:[bp],dx
add bp,byte 2
_gettext:
mov cl,byte [ds:si]
inc si
push cx
test cl,cl
jnz _output
mov [_vidmem_ptr],bp
pop word [bp]
pop ax
mov cx,0
mov ds,cx
ret
jmp $
_VIDEO_TEXT_ADDR EQU 0XB8000
_COLOR_ATTR_PSC EQU 0X6A
_COLOR_ATTR_BSC EQU 0X5F
_PM_MODE_STACK EQU 0X80000
_VM_STACK_SEG EQU 0X0000
_VM_STACK_OFS EQU 0X0000
_VM_CS_SEG EQU 0X0000
_FLAGS_VM_CMP EQU 17
_FLAGS_CMP1 EQU 1
_FLAGS_CMP_IF EQU 9
_RING0_PROC_STACK_SIZE EQU 2048
;TSS_IO_MAP_SIZE EQU 0
_TSS_IO_MAP_SIZE EQU 0x400/8
;VM_STACK_ADDRESS EQU vidmem_address
_ROWS EQU 25
_COLS1 EQU 80
_BACK1 EQU 05h
_FRONT1 EQU 12h
_CHECKER EQU 0
align 4
_vidmem_ptr: dd _VIDEO_TEXT_ADDR
_pm_str: db 'protected mode string ',0
_pm_str_length: equ $-_pm_str
;vidmem_address: dw 0
times 512-($-$$) db 0
run.sh
nasm -f bin -g -o boot.bin boot.asm
nasm -f elf -g stage1.asm -o stage1.o
nasm -f elf -g stage2.asm -o stage2.o
nasm -f elf -g stage3.asm -o stage3.o
nasm -f bin -g test2.asm -o test2.bin
ld -g -m elf_i386 -Ttext 0x7e00 stage1.o -o stage1.bin --oformat binary
ld -g -m elf_i386 -Ttext 0x8000 stage2.o -o stage2.bin --oformat binary
ld -g -m elf_i386 -Ttext 0xA000 stage3.o -o stage3.bin --oformat binary
dd if=/dev/zero of=os.bin bs=512 count=2811
cat boot.bin \
stage1.bin \
stage2.bin \
stage3.bin \
test2.bin \
os.bin>os.img
rm -rf *\.bin
qemu-system-i386 -fda os.img
(1 extra config file)
gdt.inc
%define BUILD_GDT_DESC(bounds,base,access,flags) \
((( base & 0x00FFFFFF) << 16) | \
(( base & 0xFF000000) << 32) | \
( bounds & 0x0000FFFF) | \
(( bounds & 0x000F0000) << 32) | \
(( access & 0xFF) << 40) | \
(( flags & 0x0F) << 52))
section .data
gdt32:
dq BUILD_GDT_DESC(0,0,0,0)
gdt32code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1100b)
gdt32data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1100b)
gdt16code:
dq BUILD_GDT_DESC(0x0000ffff,0,10011010b,1000b)
gdt16data:
dq BUILD_GDT_DESC(0x0000ffff,0,10010010b,1000b)
;gdt16tss:dq BUILD_GDT_DESC(0x8230,TSS_SIZE-1,10001001b,0000b) & 0 << 22
;gdt32tss:
; dq BUILD_GDT_DESC(TSS_SIZE-1,0x8280,10001001b,0000b)
; dq BUILD_GDT_DESC(TSS_SIZE-1,0x9260,10001001b,0000b)
.stub1:
code32_post: equ gdt32code -gdt32
data32_post: equ gdt32data -gdt32
;.stub:
code16_post: equ gdt16code -gdt32
data16_post: equ gdt16data -gdt32
; tss32_post: equ gdt32tss -gdt32
gdt32Len: equ $-gdt32
gdt32Ptr: dw gdt32Len-1
dd gdt32
IdtPipe:
dw 0x03ff
dd 0