flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
garystampa 13 Jul 2011, 00:24
You need to page them when you load them. 64K at a time in each segment, contiguously. Then create a base pointer and a count. Create read and write functions that are aware of this layout. You can also put them higher in memory by going in and out of PM mode.
|
|||
![]() |
|
me239 13 Jul 2011, 03:41
garystampa wrote: You need to page them when you load them. 64K at a time in each segment, contiguously. Then create a base pointer and a count. Create read and write functions that are aware of this layout. You can also put them higher in memory by going in and out of PM mode. |
|||
![]() |
|
bitshifter 13 Jul 2011, 04:31
If you seperate code/data/stack then each can be 64kb.
This is most simple and common approach. For >64kb code it need to be setup dynamically. Would your program fit into 3 segments like so? |
|||
![]() |
|
me239 13 Jul 2011, 07:23
bitshifter wrote: If you seperate code/data/stack then each can be 64kb. |
|||
![]() |
|
garystampa 13 Jul 2011, 13:08
I misunderstood what you're doing. So your EXE's are large because you've embedded BMPs in them?
Not sure what sort of EXE header you have, but there's a fix-up table in most EXE headers that points at the various segments and their offset within the EXE. You then layout the memory image and punch the true values into those locations. But since I don't know your EXE header or your OS's EXE loader I can't really tell you anymore. |
|||
![]() |
|
me239 13 Jul 2011, 16:24
garystampa wrote: I misunderstood what you're doing. So your EXE's are large because you've embedded BMPs in them? |
|||
![]() |
|
garystampa 13 Jul 2011, 19:52
They don't *have* to be 64K. They can allocate pointers and consume all available memory. The real difference is the loader: a com file is an exact image of the file as it lays out in memory and is restricted to a single 64k segment, whereas an exe has relocatable "pages" and is only restricted to available memory.
Often loaders don't actually relocate they tend to lay contiguously. All DOS exe headers have a fix-up table. This effectively tells you how many segments there are and what they're offsets (with respect to one another) should be. I'm not saying it right - it's actually pretty simple to walk through the header and poke the values into the memory where the exe is loaded. Also in DOS, uninitialized data is usually allocated by the start-up routine and then cleared to 0. Unlike a com, there's no disk space wasted with it. |
|||
![]() |
|
me239 13 Jul 2011, 20:40
garystampa wrote: They don't *have* to be 64K. They can allocate pointers and consume all available memory. The real difference is the loader: a com file is an exact image of the file as it lays out in memory and is restricted to a single 64k segment, whereas an exe has relocatable "pages" and is only restricted to available memory. EXE code: Code: format MZ entry main:start stack 100h segment main start: mov ax, text mov ds, ax mov dx, hello call extra:write int 20h segment text hello db 'Hello World!', 0 ; NULL terminated segment extra write: mov ah, 3 ; my write function int 21h retf My EXE loader code Code: mov ax, word[cs:loadseg] mov ds, ax add ax, [ds:08h] ; ax = image base mov cx, [ds:06h] ; cx = reloc items mov bx, [ds:18h] ; bx = reloc table pointer jcxz RelocationDone ReloCycle: mov di, [ds:bx] ; di = item ofs mov dx, [ds:bx+2] ; dx = item seg (rel) add dx, ax ; dx = item seg (abs) push ds mov ds, dx ; ds = dx add [ds:di], ax ; fixup pop ds add bx, 4 ; point to next entry loop ReloCycle RelocationDone: mov bx, ax add bx, [ds:0Eh] mov ss, bx ; ss for EXE mov sp, [ds:10h] ; sp for EXE add ax, [ds:16h] ; cs push ax push word [ds:14h] ; ip Run: sti retf printing code Code: int21_03: call printf popf iret printf: lodsb cmp al, 0 jz @f mov ah, 0eh int 10h jmp printf @@: ret |
|||
![]() |
|
garystampa 14 Jul 2011, 12:25
In the printing code: why are you popping the flags and issuing an iret? Usually it's either: popf, retf OR iret.
|
|||
![]() |
|
garystampa 14 Jul 2011, 12:56
I haven't built an EXE loader in many years. You've got the right idea, but I think you need to make sure your pointers are adding up correctly.
I can't see where the EXE is - I assumed you loaded it contiguously from the DS address. Also - you can ES instead of pushing and popping DS, and I don't think you want to add to the item, I think you want to mov to it. (as I remember, the location should have a 0 in it.) If you use ES:DI you can just use stosw. Debug the reloc code and before you pop the value in, disassemble the address pointed to by DS:DI minus a couple of bytes. You should see a decode for a mov reg,0000 and then mov segreg,reg. The DS:DI pointer should point at the 0000. Depending on compilers and other EXE creators - making the stack in an area other than the DS can have bad results. Many small-model EXE's expect the stack to be inside the data segment and pass everything as 16-bit - assumes the SS and DS are equal. So have a look how/why/where you're creating the stack too. |
|||
![]() |
|
me239 15 Jul 2011, 03:32
garystampa wrote: I haven't built an EXE loader in many years. You've got the right idea, but I think you need to make sure your pointers are adding up correctly. |
|||
![]() |
|
me239 15 Jul 2011, 05:45
UPDATE! I got it working! turns out STOSW doesn't work because you have to add to DI, not move to it.
|
|||
![]() |
|
garystampa 15 Jul 2011, 21:58
Actually, that doesn't really make any sense that that "fixed it". Besides, I didn't say move to di, I said if you use es:di, as a pair you can use stosw. I was just trying to suggest reducing instructions, it had nothing to do with how it was working.
|
|||
![]() |
|
me239 16 Jul 2011, 05:43
garystampa wrote: Actually, that doesn't really make any sense that that "fixed it". Besides, I didn't say move to di, I said if you use es:di, as a pair you can use stosw. I was just trying to suggest reducing instructions, it had nothing to do with how it was working. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.
Website powered by rwasa.