assembly - INT 10h/ah=13h doesn't print strings when part of second stage bootloader -
i used memory in first sector, want store new variable string in second sector (second stage) , print it. instance:
hello db 'hello world'
the new string should in sector (because there no more memory in first sector). did int 13h,ah=2 read second disk sector address 900h:0000. stored variable hello
in sector code print. fails print string when use int 10h/ah=13h in code this:
mov ax, 7c0h mov es, ax mov bp, hello mov ah,13h ; function 13 - write string mov al,01h ; attrib in bl, move cursor mov bl,0bh ; attribute - magenta mov cx,30 ; length of string mov dh,1 ; row put string mov dl,4 ; column put string int 10h ; call bios service
when variable in first sector prints well, when store in second sector doesn't print, when do:
mov ax, 900h mov es, ax
example code:
xchg bx, bx mov ax, 7c0h mov ds, ax sector_2: mov bx, 900h mov es, bx mov bx, 0 mov ah, 2 mov al, 1 mov ch, 0 mov cl, 2 mov dh, 0 mov dl, 80h int 13h call 900h:0000 jmp $ times 510 - ($-$$) db 0 ; fill empty bytes binary file dw 0aa55h ; define magic number @ byte 512 ;;;;;;;;;;;;;;;;;;;;;;;; sector_2: mov ax, 900h mov es, ax mov bp, hello mov ah,13h ; function 13 - write string mov al,01h ; attrib in bl, move cursor mov bl,0bh ; attribute - magenta mov cx,5 ; length of string mov dh,1 ; row put string mov dl,4 ; column put string int 10h ; call bios service retf jmp $ hello db 'hello' times 1024 - ($-$$) db 0 times 2*8*63*512 - ($-$$) db 0
i think there copy , paste errors in example code. wrote:
xchg bx, bx mov ax, 7c0h mov ds, ax
but think meant:
xchg bx, bx mov ax, 7c0h mov es, ax ; int 10h/ah=13h takes string address in es:bp
your code correct in first snippet. example has 2 sector_2
labels cause nasm grief. believe should remove first appearance of label in code.
i assume assembling code like:
nasm -f bin boot.asm -o boot.img
the file names different , can omit -f bin
since default.
since code doesn't have explicit org directive in it, nasm assumes org 0h
default. absolute memory references relative offset of 0. in case want first sector (512 bytes) of assembler file. have coded bootloader use segment of 0x7c0
, segment choose , origin point of 0 should point physical address of 7c00h. in segment:offset addressing you'd have (7c0h<<4)+0 (where 0 origin/org) yields proper result of 7c00h.
so , good, read sectors memory @ 900h:0h. far call first stage of bootloader via call 900h:0000
. correct.
if correct problem? issue nasm has no idea loaded code after first 512 bytes location in memory , segment:offset used relative 0 again (900h:0000h). continue generate absolute addresses relative beginning of bootloader.
if use ndisasm display generated code starting byte 512 of disk image you'd discover problem:
00000000 b80009 mov ax,0x900 00000003 8ec0 mov es,ax 00000005 bd1a02 mov bp,0x21a 00000008 b413 mov ah,0x13
this generated command:
ndisasm -e 512 -b16 boot.img
boot.img
name of image file generated. -e 512
says skip disassembling first 512 bytes of file. i'm interested in first few lines of output, in particular:
mov bp,0x21a
0x21a
offset of hello
. notice 0x21a
538 decimal , offset relative beginning of entire bootloader not relative offset of 0 (900h:0000h). fix this, need instruct nasm code generated in second stage (second sector) needs relative origin of 0 , not relative beginning of bootloader. can done placing second stage (second sector) in new section origin point (vstart) reset 0. can done placing section directive @ beginning of second stage:
section stage2, vstart=0h
so in code like:
dw 0aa55h ; define magic number @ byte 512 ;;;;;;;;;;;;;;;;;;;;;;;; section stage2, vstart=0h ; section name can of choosing sector_2: mov ax, 900h mov es, ax mov bp, hello
now if @ ndisasm output like:
00000000 b80009 mov ax,0x900 00000003 8ec0 mov es,ax 00000005 bd1a00 mov bp,0x1a ; notice hello offset 0x1a not 0x21a
@jester on right track org 0h
being placed before second stage code (second sector), there can 1 org directive in each assembly file. no matter place in file, nasm act if found @ top of file. behaviour not documented! jester's solution wouldn't have changed anything. nasm's `section directive can used anywhere in assembly file reset origin point (in case 0).
more information on org , section directives can found in nasm documentation. section directive , vstart argument documented in section 7.1.3 multisection support bin format
Comments
Post a Comment