News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

floppy image

Started by makaveli0129, October 05, 2009, 12:34:21 PM

Previous topic - Next topic

makaveli0129

Ok so i have this floppy image that just prints a message now the problem that i am running into is that i have to jump to memory location 0x1000 and then jump back to the original place but have no clue how to do it this is what mbr looks like on the floppy:

org 0x7c00
xor ax,ax
mov es,ax
mov ah,0
mov al,3
int 10h

mov ah,13h
mov al,1
mov bh,0
mov bl,0ah
mov cx,mlen
mov dh,0
mov dl,0
mov bp, msg
int 10h

;jump to 0x1000 here??????
;print '$' here

mov dh,1
msg db "This is a message"
mlen equ $-msg
times 512-($-$$)-2 db 0
dw 0AA55horg 0x7c00
xor ax,ax
mov es,ax
mov ah,0
mov al,3
int 10h

mov ah,13h
mov al,1
mov bh,0
mov bl,0ah
mov cx,mlen
mov dh,0
mov dl,0
mov bp, msg
int 10h

[b][color=Red];jump to 0x1000 here
;print '$' here[/color][/b]mov dh,1
msg db "This is a message"
mlen equ $-msg
times 512-($-$$)-2 db 0
dw 0AA55h

nathanpc

This is a boot floppy?
If it is, please declare some values at the beggining:
OEMLabel            db "SOMETHING"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "SOMETHING"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

This is in Nasm syntax(because my OS that i develop i compile in Nasm.

Hope I'm helping.

sinsi

Light travels faster than sound, that's why some people seem bright until you hear them.

makaveli0129

Quote from: nathanpc on October 05, 2009, 12:44:50 PM
This is a boot floppy?
If it is, please declare some values at the beggining:
OEMLabel            db "SOMETHING"    ; Disk label - 8 chars
BytesPerSector      dw 512          ; Bytes per sector
SectorsPerCluster   db 1            ; Sectors per cluster
ReservedForBoot     dw 1            ; Reserved sectors for boot record
NumberOfFats        db 2            ; Number of copies of the FAT
RootDirEntries      dw 224          ; Number of entries in root dir
LogicalSectors      dw 2880         ; Number of logical sectors
MediumByte          db 0F0h         ; Medium descriptor byte
SectorsPerFat       dw 9            ; Sectors per FAT
SectorsPerTrack     dw 18           ; Sectors per track (36/cylinder)
Sides               dw 2            ; Number of sides/heads
HiddenSectors       dd 0            ; Number of hidden sectors
LargeSectors        dd 0            ; Number of LBA sectors
DriveNo             dw 0            ; Drive No: 0
Signature           db 41           ; Drive signature: 41 for floppy
VolumeID            dd 00000000h    ; Volume ID: any number
VolumeLabel         db "SOMETHING"    ; Volume Label: any 11 chars
FileSystem          db "FAT12"      ; File system type: don't change!

This is in Nasm syntax(because my OS that i develop i compile in Nasm.

Hope I'm helping.

Basically all it is going to do is supposed to print the message jump to that memory location execute some code there and then jump back to where jumped from? This is just a side project nothing really useful out of it but i can't find anywhere online on how to jump to a memory location and then jump back to the place that you jumped from

BlackVortex

Just "call" there and then use "ret" to get back where you where.   :8)

makaveli0129

Quote from: BlackVortex on October 05, 2009, 01:54:08 PM
Just "call" there and then use "ret" to get back where you where.   :8)

could you give a coding example i'm not familiar with "call" or "ret"?

BlackVortex

Jesus Christ  :tdown

Learn some assembly dude !

Anyway, what I mean is that you can do a
call 1000h

and at address 1000 you have :
*your commands here*
ret

After the rest execution continues after the original call.

dedndave

lol
there isn't anything great happening at "1000", either
i would predict a hang

redskull

Quote from: BlackVortex on October 05, 2009, 02:38:29 PM
Learn some assembly dude !

Well, after all, it *is* the campus ("A protected forum where programmers learning assembler can ask questions in a sensible and safe atmosphere without being harassed or insulted").

a CALL instruction just saves the address of the next instruction on the stack (conceptually a PUSH EIP), and then jumps to the location.  the RET is the opposite; it essentially returns the address from the stack to EIP, letting the program continue on where it left off.  You might have better luck googling (or even searching MASM forum), as this is really basic stuff covered in hundreds of places.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

makaveli0129

Quote from: BlackVortex on October 05, 2009, 02:38:29 PM
Jesus Christ  :tdown

Learn some assembly dude !

Anyway, what I mean is that you can do a
call 1000h

and at address 1000 you have :
*your commands here*
ret

After the rest execution continues after the original call.

ok basically this is what is going on i followed what you said here is the mbr:

org 0x7c00
xor ax,ax
mov es,ax
mov ah,0
mov al,3
int 10h

mov ah,13h
mov al,1
mov bh,0
mov bl,0ah
mov cx,mlen
mov dh,0
mov dl,0
mov bp, msg
int 10h

call 100h

mov dh,1
msg db "Print Message"
mlen equ $-msg
times 512-($-$$)-2 db 0
dw 0AA55h


and here is what is going to reside at ox1000



[BITS 16]               ;Set code generation to 16 bit mode

[org 100h] ;set addressing to begin at 100H

start:
  call cls ;call routine to clear screen
  call dspmsg ;call routine to display message

  call date
  call cvtmo
  call cvtday
  call cvtcent
  call cvtyear
  call dspdate
 
  call time
  call cvthrs
  call cvtmin
  call cvtsec
  call dsptime

  int 20h ;halt operation (VERY IMPORTANT!!!)

  ret

cls:
  mov ah,06h ;function 06h (Scroll Screen)
  mov al,0 ;scroll all lines
  mov bh,1FH ;Attribute (bright white on blue)
  mov ch,0 ;Upper left row is zero
  mov cl,0 ;Upper left column is zero
  mov dh,24 ;Lower left row is 24
  mov dl,79 ;Lower left column is 79
  int 10H ;BIOS Interrupt 10h (video services)
  ret


dspmsg:
  mov ah,13h ;function 13h (Display String)
  mov al,0 ;Write mode is zero
  mov bh,0 ;Use video page of zero
  mov bl,0fh ;Attribute (bright white on bright blue)
  mov cx,8 ;Character string is 25 long
  mov dh,3 ;position on row 3
  mov dl,0 ;and column 28
  push ds ;put ds register on stack
  pop es ;pop it into es register
  lea bp,[msg] ;load the offset address of string into BP
  int 10H
  ret

msg: db 'My name :D'

date:
;Get date from the system
mov ah,04h ;function 04h (get RTC date)
int 1Ah ;BIOS Interrupt 1Ah (Read Real Time Clock)
ret

;CH - Century
;CL - Year
;DH - Month
;DL - Day

cvtmo:
;Converts the system date from BCD to ASCII
mov bh,dh ;copy contents of month (dh) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld],bh
mov bh,dh
and bh,0fh
add bh,30h
mov [dtfld + 1],bh
ret

cvtday:
mov bh,dl ;copy contents of day (dl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 3],bh
mov bh,dl
and bh,0fh
add bh,30h
mov [dtfld + 4],bh
ret

cvtcent:
mov bh,ch ;copy contents of century (ch) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 6],bh
mov bh,ch
and bh,0fh
add bh,30h
mov [dtfld + 7],bh
ret

cvtyear:
mov bh,cl ;copy contents of year (cl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [dtfld + 8],bh
mov bh,cl
and bh,0fh
add bh,30h
mov [dtfld + 9],bh
ret

dtfld: db '00/00/0000'

dspdate:
;Display the system date
mov ah,13h ;function 13h (Display String)
mov al,0 ;Write mode is zero
mov bh,0 ;Use video page of zero
mov bl,0Fh ;Attribute
mov cx,10 ;Character string is 10 long
mov dh,4 ;position on row 4
mov dl,0 ;and column 28
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,[dtfld] ;load the offset address of string into BP
int 10H
ret

time:
;Get time from the system
mov ah,02h
int 1Ah
ret

;CH - Hours
;CL - Minutes
;DH - Seconds

cvthrs:
;Converts the system time from BCD to ASCII
mov bh,ch ;copy contents of hours (ch) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld],bh
mov bh,ch
and bh,0fh
add bh,30h
mov [tmfld + 1],bh
ret

cvtmin:
mov bh,cl ;copy contents of minutes (cl) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld + 3],bh
mov bh,cl
and bh,0fh
add bh,30h
mov [tmfld + 4],bh
ret

cvtsec:
mov bh,dh ;copy contents of seconds (dh) to bh
shr bh,1
shr bh,1
shr bh,1
shr bh,1
add bh,30h ;add 30h to convert to ascii
mov [tmfld + 6],bh
mov bh,dh
and bh,0fh
add bh,30h
mov [tmfld + 7],bh
ret

tmfld: db '00:00:00'

dsptime:
;Display the system time
mov ah,13h ;function 13h (Display String)
mov al,0 ;Write mode is zero
mov bh,0 ;Use video page of zero
mov bl,0Fh ;Attribute
mov cx,8 ;Character string is 8 long
mov dh,5 ;position on row 5
mov dl,0 ;and column 28
push ds ;put ds register on stack
pop es ;pop it into es register
lea bp,[tmfld] ;load the offset address of string into BP
int 10H
ret

int 20H



When i combine the two the 2nd .asm file is at 0x1000 per tiny hexer but the code doesn't do anything

redskull

You are all over the map here; you are probably biting off more than you can chew at the moment, if you are unfamiliar even with  CALL and RET.  Simply cutting and pasting is not going to benefit anyone, least of all yourself.  First off, INT 20h is a DOS interrupt, and will not work if you are booting off your own floppy.  When you do your own VBR, you can only use the BIOS routines.  Second of all, when the CPU loads your boot sector, it loads ONLY that: the first 512 bytes on the disk to location 7C00.  You can't relocate the program just by using ORG 100, you have to use a REP STOSB instruction or equivalent to move your code from 7Cxx down to 100 (or wherever else you move it), and then CALL it..  Thirdly, however, loading anything to location 100 is probably a bad idea, considering the BIOS uses that system data structures.  IIRC, the generally accepted place to load anything to is x0500.  Fourthly, you won't be able to just boot up the code from a working COM file without several modifications, so don't try.  Fifthly,

Do some searching around on here; there's a new thread about writing a boot sector every few weeks, so there's lots of example code to be had.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

the interrupt vector table is down there - lol
(100h happens to be ok - that would be INT 20h, which does not exist at boot - BIOS uses INT 1Fh and below)
if you use the forum search engine and look in the 16-bit forum, you will find
a few recent threads pertaining to writing bootable sectors
save us some typing
to do what you are trying to do, disassemble a DOS floppy boot sector
they load a "bootloader" program from the data area of the floppy - similar to what you want to do
another method would be to write your own command.com - let ms take care of booting

redskull

IIRC (and it's been awhile), the IVT is "officially" 1024 bytes (256 DWORD pointers) which takes it all the way up to x400, and then there's some unstandardized bois stuff after that.  I suppose if the only the BIOS  interrupts are there (up to 19h), then you could get away with loading things all the way down at 64h, but you would run into problems if you wanted to implement additional interrupts, so I would play it safe.  But then again, i'm not the wild renaissance man dednave is! :dance:

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

lol - by "renaissance man", are you implying that i have been around since the renaissance ?   :lol
you are right - 400h - as i said, BIOS uses up to 1Fh
(several lower ones belong to the processor and things like counter/timer - interrupt controller - dma controller, etc)
but, during boot time, even BIOS temporarily uses part of the vector table for stack space (just below 0000:0400)
until YOUR OS has been loaded, the others are not defined
anything above 20h is open as "software interrupts"
meaning, they are defined by the OS that hasn't installed yet, and are not invoked by hardware
i seem to recall BIOS using one or two of the vectors as a data table for floppies
at 400h (or 0040:0000, actually) is the BIOS data area - so you have to be careful not to overwrite that

FORTRANS

Hi,

   Yes there is a bunch of stuff in the BIOS memory
segment 40H.  "The Undocumented PC" has a memory
chart.  If there are specific questions I could look them up.

   The IVT has a bunch of unused holes, but that's not
where a beginner should be starting to load code.

Regards,

Steve N.