News:

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

Tiny Memory Model confusion

Started by nmn, July 02, 2011, 03:58:43 AM

Previous topic - Next topic

nmn

Hello. I'm a 'fairly' experienced hobbyist C/++/# coder looking to expand my knowledge a bit more. I saw some pretty cool tiny little COM-based demos yesterday and was inspired to play around a little with 8086 assembly. After a bit of research, I chose MASM as my assembler.

tl;dr: I'm using MASM 6.11 on Dosbox and experimenting with Tiny Memory Model.

I'm having an issue using .data with tiny model. I know it should be possible because if I play around with exact memory addresses I can get the right address. However, because it (apparently) is being stored after the code, I can't really rely on that (not to mention it's hackish and unreliable.)


.model tiny
.data
  msg db "Hello, World!$",0
.code
  start:
    org 100h
   
    mov ah, 09h
    lea dx, msg
    int 21h
    ret
  end start


I feel like there's plenty of room for issues, but I wasn't able to figure it out on my own.

Thanks for reading.

dedndave

for tiny model programs, all code and data must reside in a single segment, as well as the stack space
i.e., all code and data are in the code segment (which is also the PSP segment)
when the program is loaded, CS, DS, ES, and SS all have the same segment value
you can move things around to other segments after load, however
the SP register will normally contain 0FFFEh, so that the stack is at the end of the segment

i haven't played with .COM's much under the newer assemblers
but, give this a try...
        .MODEL  Tiny

        .CODE

        ORG     100h

_main   PROC    NEAR

        mov     dx,offset msg
        mov     ah,9
        int     21h
        mov     ax,4C00h
        int     21h

_main   ENDP

msg     db "Hello, World!",0Dh,0Ah,24h

        END     _main


also....
here is a little batch utility that will execute 16-bit code as a .COM program from the command line   :bg
http://www.masm32.com/board/index.php?topic=13032.msg101106#msg101106

nmn

Thanks for the timely response. You're right, and I should've guessed there were no sections considering COM is just raw instructions.

This code works fine.

MichaelW

#3
Placing the start label immediately above the org 100h puts the label at offset 0 in its segment, and the org 100h then causes the assembler to add 100h zero bytes between the start label and the first instruction. Since the loader loads the program into memory starting at offset 100h, at run time everything in the program is at a higher address than it should be, by 100h bytes. The program executes the zero bytes as a series of 80h ADD [BX+SI], AL instructions, harmlessly since BX and SI are both zeroed, before it executes the actual code. The solution is to place the start label immediately below the org 100h:

.code
    org 100h
  start:

eschew obfuscation

dedndave

at PSP:0000 is a terminate (INT 20h), so the program will exit immediately   :P

the loader also pushes a 0 at SS:SP, so a RETN executes the same code

MichaelW

Quote from: dedndave on July 02, 2011, 11:48:08 AM
at PSP:0000 is a terminate (INT 20h), so the program will exit immediately

It would if the start address were at PSP:0000, but for a .COM file the start address is PSP:0100
eschew obfuscation

dedndave

i see what you are saying, Michael   :P

what is worse - all the offsets (like the "msg" string) will be off by 100h

nmn

I'm glad to be hearing all of this, since it was a bit unclear in my head, and reading this stuff is solidifying some concepts, but are there any other resources you'd recommend for this? I'm in the process of reading manuals and playing with code right now. Pretty much anything would probably help at this point; this is my first real attempt to learn 8086 assembly language.

Since there's so little about DOS COM files, and so much more about bootloaders, would it be better to start out toying with bootloader tutorials? I know I'd lose the MS-DOS API if I did that, but that doesn't bother me. I don't know anything about DOS programming in the first place.

dedndave

this is all obsolete stuff - lol
it really depends on what you wish to learn/accomplish
there is no 32-bit equivalent of .COM programs

if you just want to write programs, learn 32-bit windows
if you want to write bootloaders, 16-bit code is necessary, only enough to load code and get to protected mode

Ralf Brown's Interrupt List has a section that explains the PSP
that is about all the documentation there is about .COM programs
initially, MS had no intention of users writing .COM programs
it was intended as a mechanism for loading COMMAND.COM and some DOS external commands

FORTRANS

Quote from: nmn on July 02, 2011, 01:18:36 PM
Since there's so little about DOS COM files, and so much more about bootloaders, would it be better to start out toying with bootloader tutorials? I know I'd lose the MS-DOS API if I did that, but that doesn't bother me. I don't know anything about DOS programming in the first place.

Hi,

   That depends on what you want to accomplish.  DOS has
a file system and BIOS does not.  So if you want to save any
results from your program, it is a lot easier in a DOS environment.
It also has the DEBUG program.  Which can show what is actually
happening, rather than what you think should be happening.

   If you want a reference on DOS, I have used the following
books.  "Microsoft MS-DOS Programmer's Reference Version 5",
ISBN 1-55615-329-5.  Version 6 made some corrections.
"Advanced MS-DOS" by Ray Duncan, ISBN 0-914845-77-2.
(Maybe available on the Internet?)  "Undocumented DOS
Second Edition" by Andrew Shulman and others, ISBN
0-201-63287-X.

   If you want to learn assembly language, try a text book.
16-bit "Structured Assembler Language for IBM Microcomputers" by
Alton R. Kindred, Oxford University Press, 1991, ISBN: 0-19-517296-5.
And Art of Assembler (?) by Randy Hyde available at his site
both 16 and 32-bit versions, though in his own format assembly
language.

Regards,

Steve N.

P.S.  As Dave says 16-bit is considered obsolete by most.
So tell us what you want to accomplish if what we are telling
you is wrongish.

SRN

nmn

Okay - I'll clarify my intentions.

Quote from: dedndave on July 02, 2011, 01:33:56 PM
this is all obsolete stuff - lol
Quote from: FORTRANS on July 02, 2011, 01:45:05 PM
P.S.  As Dave says 16-bit is considered obsolete by most.
So tell us what you want to accomplish if what we are telling
you is wrongish.
That's a fair and good point. As I stated above, my main inspiration was the demoscene and its tiny COM demos, but also an interest in coding outside of a formal operating system. It's not that I'll do much with it other than play around, but.. I don't know, I suppose you'd understand as well as I do at this point. I'm sure you get this a lot, after all.
Quote from: dedndave on July 02, 2011, 01:33:56 PM
it really depends on what you wish to learn/accomplish
there is no 32-bit equivalent of .COM programs
Yes, and based on reading I can understand why there's no equivalent. Obviously PE-COFF is superior to COM, by design.
Quote from: dedndave on July 02, 2011, 01:33:56 PM
if you just want to write programs, learn 32-bit windows
if you want to write bootloaders, 16-bit code is necessary, only enough to load code and get to protected mode
I could learn assembly with 32-bit Windows first, or Linux/Mac OS X for that matter (though I guess that throws Masm out the window,) but I kind of decided to go cold turkey here and try to learn some new stuff.
Quote from: FORTRANS on July 02, 2011, 01:45:05 PM
That depends on what you want to accomplish.  DOS has
a file system and BIOS does not.  So if you want to save any
results from your program, it is a lot easier in a DOS environment.
It also has the DEBUG program.  Which can show what is actually
happening, rather than what you think should be happening.
I'm not bothered by the lack of a filesystem, really. Something like FAT with no extensions doesn't sound too intimidating... It's more a matter of getting up-to-par with assembly coding first. It's (obviously) different from coding on programming languages. On that note, I'm sure once I'm in protected mode I can get some C code to run that doesn't use the standard libraries, but I'd rather avoid it if possible for now.

If I were to jump outside of DOS, is there an effective way to debug code? I'd probably start out in Qemu or another emulator (any recommendations? I don't remember seeing any debugging tools in any of the VMs I used...)
Quote from: FORTRANS on July 02, 2011, 01:45:05 PM
If you want a reference on DOS, I have used the following
books.  "Microsoft MS-DOS Programmer's Reference Version 5",
ISBN 1-55615-329-5.  Version 6 made some corrections.
"Advanced MS-DOS" by Ray Duncan, ISBN 0-914845-77-2.
(Maybe available on the Internet?)  "Undocumented DOS
Second Edition" by Andrew Shulman and others, ISBN
0-201-63287-X.

If you want to learn assembly language, try a text book.
16-bit "Structured Assembler Language for IBM Microcomputers" by
Alton R. Kindred, Oxford University Press, 1991, ISBN: 0-19-517296-5.
And Art of Assembler (?) by Randy Hyde available at his site
both 16 and 32-bit versions, though in his own format assembly
language.
That might be helpful. When it comes down to it, I might just skip DOS altogether and start on the lowest level. It can't be much worse considering I have no assembly or DOS experience to begin with.

Thanks for your help.

dedndave

well - we have all done the same thing   :P
at least, Michael, Steve, and I have - lol
we are "old guys", and we learned a lot by playing with code, sometimes in DEBUG
back then, DOS on an 8088 was the machine of the day
what you learned by going through that process was applicable to then modern code

nowdays, that is a limiting approach
better to start out with a few console mode 32-bit trivials, and maybe Iczelions tutorial to make your first GUI app

Olly debugger is a good choice for 32-bit code, although there are a few others
http://www.ollydbg.de/

nmn

I do understand that this is not applicable to most code. That's not really discouraging.

Are you suggesting I'd be better off at starting with 32-bit assembly regardless of what else I want to play with? If that's the case, I'll just stick to that for now.

dedndave

yah
the stuff you learn will be more usable on future projects

there is much to learn to write effective 16-bit code
it will be a lot of relatively wasted time

part of it is easy to explain
the stuff about segmented addressing is unnecessary
system services via BIOS and DOS interrupts - also a waste of time

part of it is not so easy to explain
when you learn 16-bit code, you actually develop "habits" that hurt you in the 32-bit world
and, you miss out on many instructions and instruction extensions that are available

there is a lot more to learn for 32-bit code
the windows API is daunting
the extended instruction sets (like SSE) - also daunting
the list goes on and on
but - at least the stuff you learn is sometihng you can use

nmn

Alright, I'm going to do as you say then. I'm fairly familiar with Win32 programming in C.

Since this thread is going off-topic, I assume I should keep it brief. Now that I'm switching to 32-bit assembly, though, are there any good docs I can grab for a quick reference? I'm downloading and installing the MASM distribution from this site now, so I'll find out what documentation it comes with. I can imagine where I'm going to fail at is writing good, optimized and safe code, so that's my primary concern.

edit:
Quote
the windows API is daunting
the extended instruction sets (like SSE) - also daunting
the list goes on and on
but - at least the stuff you learn is sometihng you can use

I'm sorry if I was being unclear earlier. I'm already familiar with low level programming as far as C goes, so the API is no problem at all.