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

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -