flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
DOS386 16 Sep 2008, 02:15
> I don't know what to do after loading the program to the memory?
Start it. ![]() Code:
jmp far seg:off
Code: ; place far return address on the stack if you want to return with RET ; AX has our segment address pushw ax ; seg xor ax,ax push ax ; off retfw > also is there a specific memory address the program should be loaded into it? NO, anywhere where it's free, preferably 16-bytes aligned (so your "off" can be 0 as above). BTW, if you are loading DOS COM's, your "off" and org must be $0100, not 0, also you must supply far return address on the stack, and support INT $20 and int $21/AH=$4C. |
|||
![]() |
|
abuashraf 16 Sep 2008, 04:06
hmm...
here's my code: Code: intialize: ;intializing interrupts table push ds cli ;ints off mov word [es:21*4], int_21 ;move the offset mov word [es:21*4+2], cs ;move the segment into the interrupt table sti ;ints on pop ds ret int_21: ;get input from the user xor ah,ah ;al contains the char int 16h ;print out the char call putc iret I know I did't discuss the service number (ah value),just for simplicity as this is the only int tell now in my os I load the program at [es:0x200] Code: mov ax,es pushw ax ;seg xor ax,ax mov ax,0x200 push ax ;off jmp far [es:0x200] retfw would you please tell what I'm doing wrong here? Thanx. |
|||
![]() |
|
DOS386 16 Sep 2008, 04:48
There are multiple ways how to start your application:
1. CALL FAR (pushes return far address, RETFW will work to terminate / return) 2. JMP FAR 3. RETFW So you must use just __ONE__ of them, and for 2 and 3 manually push a far return address __OR__ use an INT to terminate. Also ES must be 0 when used for writing into the IVT, but non-ZERO and sufficiently high for your es:$0200 address. |
|||
![]() |
|
Dex4u 16 Sep 2008, 15:02
You should take a look at MiniDos http://board.flatassembler.net/topic.php?t=5275&start=0
As for load code example Code: The above will run a com or mz exe . |
|||
![]() |
|
edfed 16 Sep 2008, 16:56
very cool job dex.
load exe is my nightmare. then i only load com using my own version of PSP. Code: ;this is the file coordinates file: db 2,81h ;read on D:/ dw 128 ;128 sectors dd 0ffff8844h ;from C=0ffffh, H=88h, S=44h dd 1000h:0100h ;at 1000h:0100h dd 0 ;drive geometry, in CCCCHHSS, updated each drive operation on the item. it is loaded in memory @ segment:0 Code: ... mov si,file mov ax,[si+disk.seg] mov es,ax xor bx,bx mov cl,psp.end-psp mov di,psp @@: mov ax,[di+bx] mov [es:bx],ax add bx,2 dec cl jne @b ; after, the .com file is loaded using disk function. mov [si+disk.drv],dl call disk ; simply relocate the offset in the far pointer pointed to by si+disk.off ; then, it will call the far address [segment:offset] mov word [si+disk.off],0 ; it will be called as a far address, @ segment:offset call far dword[si+disk.off] ; reset the offset with 100h value if we continue to use this object as org100h. mov word [si+disk.off],100h ... no need of org for this simple code, but shall be orged at 0 if it uses relative addressing Code: psp: push cs pop ds mov ax,100h ; and it will just call the near address, 100h call ax ;then, to quit, only a simple ret is needed, ;it is to the psp to do the retf, not the application of course. retf .end: ;and building an advanced PSP is not a pb. align 100h this comloader method is interresting, it permits to have the minimal .com program size = 1 byte. Code:
org 100h
ret
|
|||
![]() |
|
abuashraf 18 Sep 2008, 04:43
right now I'm very confused,the only thing I'm sure of it is
cs = ds = es = ss = 50h, sp = 0, ip = 100h but nothing else,would you please guys explain stuff to me step by step. @Dex: in the example you post,where did the program was loaded? I load the program at es:0x200 Also would you please explain this to me: Code: mov dl, [cs:bsDriveNumber] ; let program know boot drive mov dh, 0xff ; let DexOS know it booted from its bootloader Thanx. |
|||
![]() |
|
Dex4u 18 Sep 2008, 15:28
Ok here goes, when the above code says load address 60h the real address is 600h ( because of the realmode address are make up of seg and offset.
Now 600h is dec 1536 Now how a com file is load is in this case, it's load to 60h (real 600h ), then because of the ORG 100h that all com file have, we sub 10h (real 100h) off the 60h (real 600h) and set cs = ds = es = ss to 50h (real 500h) then es is push (=50h real 500h) and 100h is push for offset together the address = 60h (real 600h). So a com file is load with a blank space before it, 100h in size eg: ***50h*** ; <cs = ds = es = ss (real address 500h ***60h*** ;< this is the load address (real address 600h) Next when a com file is loaded it should have DL filled with the boot drive, in the above example the var [bsDriveNumber] containeds the boot drive eg: 0 = A:, 80h = C: etc. The other part is for DexOS, as i need to know if it booting from Dos or the bootloader. I hope this helps as i am not good at explanions. |
|||
![]() |
|
abuashraf 19 Sep 2008, 04:13
Thank you Dex for your help,
so I should load my program at 50:100,is that right? I tried this but it's not working,here's my code: Code: mov cx,1 ;read one sector mov bx,50 mov es,bx mov bx,[es:0x100] ;buffer for loaded file call read_sectors ;invoke BIOS mov ax, 60h mov es, ax cli ; for stack adjustments mov ax, es sub ax, 10h ; "org 100h" stuff mov es, ax mov ds, ax mov ss, ax xor sp, sp push es push word 100h mov dl, 0 sti retf pop ax es every time I run the program my kernel just reloaded. Thanx. |
|||
![]() |
|
Dex4u 19 Sep 2008, 15:18
You have put 50 instead of 50h
And i do not know how your read function is written, but normaly it users es:bx So you would use something like this: Code: mov ax,60h mov es,ax xor bx,bx Before calling function. |
|||
![]() |
|
abuashraf 20 Sep 2008, 02:17
Hi,
you are right Dex the buffer is at es:bx,usuallly when I use the function read_sectors,I use this combination: Code: mov bx,[es:0x100] I tried what you adviced me but unfortunatelly my os just freezed, so here's what I got: code to load and execute Code: mov cx,1 ;read one sector mov bx,60h mov es,bx xor bx,bx ;buffer for loaded file(es=60h,bx=00) call read_sectors ;invoke BIOS mov ax, 60h mov es, ax cli ; for stack adjustments mov ax, es sub ax, 10h ; "org 100h" stuff mov es, ax mov ds, ax mov ss, ax xor sp, sp push es push word 100h mov dl, 0 sti retf pop ax es for intializing the interrupt table: Code: intialize: push ds cli ;ins off mov word [es:21*4], int_21 ;move the offset mov word [es:21*4+2], cs ;move the segment into the interrupt table sti ;ints on pop ds ret Also: Code: int_21: ;prints a single char from al call putc iret and here's my prog: Code: org 100h mov al,'m' int 21h Thank you for your help. |
|||
![]() |
|
Dex4u 20 Sep 2008, 15:55
First try these
Code: Installints: push ds ; Save DS cli ; Turn off int's xor ax,ax mov ds,ax ; 0 DS mov word [ds:21h*4],int21 ; load int vecter with int21h address mov word [ds:21h*4+2],cs ; + CS sti ; Turn on int's pop ds ; restore DS ret ; Return And Code: org 100h mov al,'m' int 21h jmp $ As first you need to make sure ds or es is zero for the int vector and as theres no return, you best just loop for now at end of com file code. If they do not work, post your read floppy function. |
|||
![]() |
|
abuashraf 20 Sep 2008, 22:46
Hi,
It didn't work,it suppose to print 'm',but unfortunatelly ,it didn't. it just freezed . here's my read_sectors: Code: read_sectors: push di @main: mov di,5 @sectorloop: push ax bx cx dx call lbachs mov ah, 0x02 ;BIOS read sector mov al, 0x01 ;read one sector mov ch, BYTE [track] ;track mov cl, BYTE [sector] ;sector mov dh, BYTE [head] ;head mov dl, 0 ;drive int 0x13 ;invoke BIOS jnc @success xor ax,ax int 0x13 dec di pop dx cx bx ax jnz @sectorloop int 0x18 @success: pop dx cx bx ax add bx,0x200 ;add 512 bytes to buffer inc ax loop @main pop di ret and lbachs: Code: lbachs: push dx bx ax cx ;Save the value in dx xor dx,dx ;Zero dx mov bx, 18 ;Move into place STP (LBA all ready in place) div bx ;Make the divide (ax/bx -> ax,dx) inc dx ;Add one to the remainder (sector value) push dx ;Save the sector value on the stack xor dx,dx ;Zero dx mov bx, 2 ;Move NumHeads into place (NumTracks all ready in place) div bx ;Make the divide (ax/bx -> ax,dx) mov cx,ax ;Move ax to cx (Cylinder) mov bx,dx ;Move dx to bx (Head) pop ax ;Take the last value entered on the stack off. ;It doesn't need to go into the same register. ; Restore dx, just in case something important was ; originally in there before running this. and al,11111111b ;make some bitwise operations mov [sector],al ;tostore the results in byte variables and bl,11111111b mov [head],bl and cl,11111111b mov [track],cl pop cx ax bx dx ret sector,head and track are defined as bytes, the thing is I'm pretty sure of this functions,becuase I wrote FAT12 driver read/write and it works fine. an example: Let's Assume I want to print the folders/files name from the first sector in the root directory,here's what I do: Code: mov bx,[es:0x400] ;the buffer xor ax,ax ;zero ax mov cx,ax ;zero cx mov dx,ax ;zero dx mov ax,19 ;first sector of the root directory mov cx,1 ;read one sector call read_sectors call printbuffer Code: ;-----------------------------------------------; ; di points to the buffer ; ; bx points to the current char ; ; dx counts the length of the file name ; ;-----------------------------------------------; printbuffer: xor ax,ax ;zero ax mov bx,ax ;zero bx mov dx,ax ;zero dx mov si,ax ;zero si mov di,ax ;zero di mov di,[es:0x400] ;di points to the buffer mov cx,16 ;number of root directory entries @loop: test byte[di+0x0b],1 shl 3 ;is it a volume label? jnz del ;don't print it cmp byte [di],0xE5 ;is it deleted file? je del ;yes, don't print it cmp byte [di],0x00 ;is this the end of files/directories? je quit ;yes,quit no: ;no... push cx ;start printing the names mov cx,11 call printname pop cx add di,21 ;go to the next entry xor bx,bx ;make bx zero xor dx,dx ;make dx zero jmp again ;continue printing! del: add di,32 again: loop @loop ;continue printing! quit: ret I think the problem is in the buffer address(I'm not sure). Thank you very much for your help. |
|||
![]() |
|
neville 21 Sep 2008, 03:50
If Dex doesn't lose his patience with you quite soon, then he must be a saint!
![]() My advice is that you should think twice about doing ASM, and especially about trying to write an OS with your present level of knowledge. You can not learn this way (by asking disjointed questions one by one on this board) - you obviously need to take a properly structured course, attend regularly, and learn methodically, step by step, following and understanding all the examples given. Until that happens I honestly feel you are likely to become even more confused and many of us will become more frustrated, including you More specifically: Writing an even simple OS requires some structure which you dont have. Displaying a single char on the screen and then allowing it to wander into neverland or looping forever is not a good idea. Very hard to test! Why is your Boot & Exec code freezing? 1. Its difficult to tell if you've set everything up correctly e.g. the IVT entry for INT_21, your INT_21 ISR, the bootsector itself .... 2. You have set the stack to 50h:0h which means it will extend downwards into the BIOS data area. How many bytes does your subsequent INT call put on the stack? ANS: 6 3. CS:IP on booting is usually 0:7C00h but is 7C0h:0 with some BIOS's Do you know where CS really is? Also: POPs after the RETF won't be executed... What is the purpose of AND AL,11111111h etc in LBACHS? (rhetorical Q!) Good luck! I've said what I think needs to be said. I see you've been on this board for nearly 2 years (while I've only been here for 2 months). Please don't think I'm trying to be mean to you - just because I once criticised your putc subroutine which calls itself. I sincerely believe you should heed my blunt, but heart-felt advice ![]() _________________ FAMOS - the first memory operating system |
|||
![]() |
|
abuashraf 21 Sep 2008, 04:45
Quote: If Dex doesn't lose his patience with you quite soon, then he must be a saint! Dex was very helpfull,and I learnt alot from him. Quote: Writing an even simple OS requires some structure which you dont have. Displaying a single char on the screen and then allowing it to wander into neverland or looping forever is not a good idea. Very hard to test! I think you are missing the point here,I'm trying to add support to .com progs in my os,so for the simplicity this program is going to print a single char. Quote: Good luck! I've said what I think needs to be said. I see you've been on this board for nearly 2 years (while I've only been here for 2 months). Please don't think I'm trying to be mean to you - just because I once criticised your putc subroutine which calls itself. I sincerely believe you should heed my blunt, but heart-felt advice Don't worry about that,I know that your intentions are good. Also I've fixed that procedure. Maybe I'm here for about two years,but I started coding and spending some time with asm,in the middel of this summer,so it's about two mounthes,Also in this two mounthes I wrote a real mode os and I learnt alot from this experience. they only thing left todo in this real mode os is loading and executing .com prog and sure implementing some Dos INTs(the famous). |
|||
![]() |
|
Dex4u 21 Sep 2008, 18:29
One thing, which i have pointed out before is your addressing is wrong for your read sector function, you pointing to whats in the address, not the address.
Try using this in your com file code Code: pusha push es mov ax, 0B800h mov es, ax mov byte [es:0], "M" pop es popa In stead of your int 21h, also in your code add something like this untill you find the problem Code: pusha push es mov ax, 0xB800 mov es, ax mov byte [es:0], "1" pop es popa ;some code here pusha push es mov ax, 0xB800 mov es, ax mov byte [es:0], "2" pop es popa ;some code here pusha push es mov ax, 0xB800 mov es, ax mov byte [es:0], "3" pop es popa ;some code here pusha push es mov ax, 0xB800 mov es, ax mov byte [es:0], "4" pop es popa ;some code here ; more here etc And see what number you get too, before it crashs. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.