I have been reading MS-DOS 1.00 source code. Link: https://www.pagetable.com/?p=165
One of the times where the developer decided to save a register, that is preserved by BIOS?
print xor bh, bh ; XXX unnecessary
print_loop lodsb
and al, 0x7F ; clear bit 7 XXX why is it set?
jz ret0 ; zero-termination
push si
mov ah, 0x0E
mov bx, 7 ; light grey, text page 0
int 0x10 ; write character
pop si
jmp print_loop
ret0 retn
So LODSB increments (but there was no CLD before? I thought it's necessary to clear or set DF flag in your bootloader before using LODSB and the like?) - So LODSB probably increments SI, then there is some weird instruction (which I read from the comment section is needed to save one byte in strings?), then PUSH SI before using interrupt and POP SI after.. I guess the developer was really afraid there's some bios version that does not preserve SI after INT 10h?
start cli
mov ax, cs
mov ds, ax ; DS := CS
mov dx, 0
mov ss, dx ; SS := 0000
mov sp, 0x7C00 ; stack below code
sti
mov ax, [os_segment]
mov ds, ax
mov es, ax ; ES := DS := where to load DOS
mov dx, 0
mov ax, dx
int 0x13 ; reset drive 0
jc disk_error
again call check_sys_files ; check for presence of IBMDOS/IBMBIO
jc again ; not found, try another disk
mov cx, [cs:os_numsectors]
push cx ; remaining sectors
mov bx, 0
xor dx, dx ; drive 0, head 0
mov cx, 8 ; track 0, sector 8
mov si, 1 ; read 1 sector in first found
push si
mov al, 1 ; 1 sector
read_loop mov ah, 2
int 0x13 ; read sector(s)
jc disk_error
pop si ; sectors read
pop ax ; remaining sectors
call add_si_sectors ; bx += si*512
sub ax, si ; remaining -= read
jz done ; none left
inc ch ; next track
mov cl, 1 ; start at sector 1
mov si, 8 ; read up to 8 sectors
cmp ax, si ; how many are left to read?
jae at_least_8_left ; at least 8
mov si, ax ; only read remaining amount
jmp short skip
at_least_8_left xchg ax, si ; read 8 sectors this time
skip push si ; number of remaining sectors
push ax ; number of sectors to read this time
jmp read_loop ; next read
done jmp far [cs:os_offset]; jump to IBMBIO.COM
disk_error mov si, FAILURE ; string to print
mov ax, rom_basic ; put return address of "int 18" code
push ax ; onto stack
Another PUSH SI before int 13h.. But this time I don't know if the INT 13h is the reason, I haven't yet read the entire code after it, maybe there is the real reason.
So why is there PUSH SI in the print function at least?