DPRG List  

DPRG: Assembler -- here is a try at the fix.

Subject: DPRG: Assembler -- here is a try at the fix.
From: TopOne top.one at usa.net
Date: Sun Jul 27 13:43:22 CDT 1997

droid at bellatlantic.net wrote:
> Kipton Moravec wrote:
> > Depending on the project, and what I am trying to accomplish, sometimes,
> > I prefer assembler!  If the project is small, and speed is important or
> > I am manipulating hardware, I usually prefer assembler. If I have to
> > worry about writing to the screen, and deal with user input I will NOT
> > use assembler. Assembler should be used if you want to take advantage of
> > the special features of the processor or controller.  If you want to be
> > generic, then use a higher level language.

I think you missed the paragraph above!  This is exactly where I will
NOT use assembler, writing to the screen. :)

> Well...Kip...since you are the brains here in the assembly
> headquarters...I got to ask you a question. There is a short program
> which I have gotten from the WWW. It supposibly displays the text "Hello
> World" but after I compiled it with a86 assembler...helllit displays a
> jink beeps like crazy and then either resets or gets stuck or returns to
> DOS prompt :(

Before we go any farther you need to be running this in DOS and NOT in
Windows.  Windows should not be loaded.

> Would you take a look at it ?

It has been a while since I wrote 386/486/Pentium assembler. So I
probably will not get this right the first time. :)  But this is where
it helps to have a lot of books, like "System BIOS for IBM PC/XT/AT
Computers and Compatibles". In there it says INT 10h is video service.  

This is a page from the book.

- ---------------------------------------------------------------------------
Function AH = 13h Write String

The write string function operated similarly to Write Teletype to Active
Page Function (AH = 0Eh), except that an entire string is handled with
each call.  The AL register contains two single-bit fields
differentiated as follows:

AL bit 0 = 1    The Cursor remains at the character written
AL bit 0 = 0    The cursor is restored to where it was before the write
string                 operation began.
AL bit 1 = 1    each string character to be displayed is followed by its
AL Bit 1 = 0    carrage return, line feed, backspace, and bell are
interpreted as
                commands, rather than as printable characters, and the
                is taken from the BL Register.


Input   AH    = 13h
        ES:BP = Pointer to start of string
        BH    = Page Number (for text modes)
        BL    = Attribute for characters (Graphics Mode)
        CX    = Length of string (Attributes don't count)
        DX    = Starting Cursor Position (DH = row, DL = Column)
        AL    = 00h Cursor is not moved
              = 01h Cursor is moved
              = 02h Cursor not moved (Text mode only)
              = 03h Cursor is moved (text mode only)

Output  None

- ------------------------------------------------------
Whoops, I just realized why INT 21 is not in the book! It is not a BIOS
call, it is a DOS call!

O.K. New book. "Microsoft MS-DOS Programmer's Reference" Hmmm, You are
calling the int correctly.  So that means it is a assembler specific
problem.  The directives for an assembler are assembler specific.  I
think you said you were using Borland, awhile back, so it is TASM.

Yet another book, "Turbo Assembler's Users Guide, Version 1". (I told
you I was old <grin>).  It has some of the assembler directives a little

First step, Lets type it like assembler should look.  In the line Column
1 usually has the label.  Then tab to the operand, then tab to the
variables, then usually somewhere around 32 or 40 start the comments. 
You do not have to end a line with a ;. It identifies the start of a

Here is how I would do it:

- ------------------------------------------------------------------------------

        .MODEL  small
        .STACK  200h

Message DB      'Hello World$'      ; message to be displayed



        mov     ax,SEG Message      ; segment of Message is in AX
;       mov     ax, at data            ; This is how Turbo Assem, book does
same thing
        mov     ds,ax               ; DS:DX points to string
        mov     dx,OFFSET Message   ; offset of message is in DX
        mov     ah,9                ; function 9 - displays string
        int     21h                 ; call for dos service

; This call looked O.K., I changed the order for convention, that
usually you 
; set the segment first.  It really does not affect the result. 

        mov     ax,4c00h            ; return to dos DOS
        int     21h                 

; This call looks O.K. In the mov ax you are loading 4ch into ah for 
; the function, and 00h into al for the return code. 

        end     ProgramStart        ; end here
- -------------------------------------------------------------------------

If it assembles without an error, then you are in the right direction. 

I think the biggest problem was the " instead of the ' around the data
in Message.

> Now...you have no idea of how many things I ahve tried on this sucker.
> So many versions that my head is steaming. I mean I have not used the
> semicolons, semicolons but no comments...I mean tons of stuff...changing
> model ... and all. I just want this sucker to display this goddamn "Hello
> World" ( I know it seems kind of corny but  that's what most people get
> started with when they learn the new programming language) Can you tell
> me what I'm missing there or what is misspelled or maybe something too
> much...hell I don't know.
> Really need help.

It has been ages since I wrote '386 assembler.  I find for the PC it is
better to call the assembler from within a C program using the inline
assembler routines.  

I once wrote a program in C, with inline assembler in the speed critical
places,that would read 80K 16-bit words per second from a DMA card, and
write it to disk, after throwing away unimportant records. The data
would come nonstop for up to 3 hours.  The DMA card was off the shelf,
and did not have any buffering capabilities.  The data was coming at a
constant rate with no handshaking, so I could not slow it down, stop it,
or let the sender know whether I got the data or not.  I wrote the
program .

It would read a 64K byte chunk of data, send me an interrupt, and before
the PC could respond to the interrupt, and reset the DMA, to a new
memory location, I would lose 3 to 30 words of data (even with
assembler). It took about two weeks to get that to work. I had to
understand the GUTS of the PC DMA controller. I ended up using it in a
way it was NOT intended, but would work for my specific application.  It
was a convoluted technique, that still takes me a day to figure out
exactly how it works.  Fortunately, it is still working after 8 years,
and it is being used in Italy, to support the German Air Force
Reconnaisance missions over Bosnia.  I am hoping that it will break one
day, and they have to call me to fly to Italy to fix it. :) 




More information about the DPRG mailing list