input & output in assembly

  • Follow


in 16-bit assembly is there any way to accept numbers as input and display them.
btw, is there anything like cin & cout in assembly

PS. I'm a complete newbie so plz excuse

0
Reply dpakch3r1an 1/24/2004 12:33:38 AM

Dpak Cherian wrote:
> in 16-bit assembly

I'm slightly curious why you care about 16-bit ASM in the modern day.
Actually, I'm not curious, that's the wrong word.  I'm saying you shouldn't
be bothering with 16-bit ASM for any reason.  32-bit is minimum.  The only
16-bit systems of interest are "retro" HW platforms for old games and the
like, and there's no reason you should learn those at a first go.

> is there any way to accept numbers as input and
> display them. btw, is there anything like cin & cout in assembly
>
> PS. I'm a complete newbie so plz excuse

Assembly is the lowest level of coding you can do for a computer, short of
giving it 1's and 0's directly.  Assembly is generally used to build an
Operating System from scratch.  In fact, not even that, just parts of an
operating system.  Most parts of an OS are built in a slightly higher level
language like C.  cin, cout, cerr, and "displaying" numbers are all
exceedingly high level capabilities compared to ASM code.  ASM code just
allows you to push values into and out of a CPU, and other extremely basic
OS tasks.

In other words, no.  Not in ASM itself.

If your *development tool* has a way of displaying numbers as an ASM program
executes, that's a different matter entirely.  But that has nothing to do
with ASM itself, that is a capability of the tool.  No tool, no numbers.

The way ASM + CPU turns into an actual OS and computer that can do I/O, is
you have specialized pieces of hardware that do various things when you read
/ write values to specific memory addresses.  This is entirely CPU,
controller chipset, and OS specific.  Generally speaking such techniques are
called "memory mapped I/O."

-- 
Cheers,                     www.indiegamedesign.com
Brandon Van Every           Seattle, WA

20% of the world is real.
80% is gobbledygook we make up inside our own heads.


0
Reply Brandon 1/24/2004 4:00:09 AM


Dpak Cherian wrote:

> in 16-bit assembly is there any way to accept numbers as input and display them.
> btw, is there anything like cin & cout in assembly

Not really. You need to rely on the services of a specific OS to do 
anything like that, and what the OS gives you will not be as simple as 
what C++ has.

You can look up various references about doing things like this once 
you've decided which OS you will use. If you are using 16-bit Intel 
chips (the 8088/8086 up to the 80286), the OS will probably be some 
variant of DOS (MS-DOS, PC-DOS, DR-DOS, FreeDOS, etc.).

I have a question for you: Why do you want to use 16-bit chips? 32-bit 
chips are more common now, certainly cheaper (all 16-bit Intel chips are 
now antiques), and they do not impose as many restrictions on you. Plus, 
with 32-bit chips you can use much better OSes (Linux, OpenBSD, Minix, 
etc.).

> 
> PS. I'm a complete newbie so plz excuse
> 

Nobody will hold that against you here, as long as you make some effort 
to do things for yourself.

-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/24/2004 4:00:46 AM

"Dpak Cherian" <dpakch3r1an@fastmail.fm> wrote in message
news:476dbfa6.0401231513.3b3e4cbc@posting.google.com...
> in 16-bit assembly is there any way to accept numbers as input and display
them.
> btw, is there anything like cin & cout in assembly
>
> PS. I'm a complete newbie so plz excuse
>

it's all done manually.. you have to know where you want the input to come
from... what data format it is in (ASCII numbers? packed BCD numbers? signed
32-bit integer? 80-bit floating point? etc.).... and after processing it..
you have to know where you want to place it..

if you could be so kind as to give a more specific (yet very basic)
question, i'll gladly supply an example answer....


0
Reply Bx 1/24/2004 4:00:47 AM

I agree with others who claim you should steer clear of 16-bit DOS
code these days. But if you insist, take a look at the "UCR Standard
Library for 80x86 Assembly Language Programmers" It has the routines
you're looking for, and many more. You can find the UCR stdlib at
http://webster.cs.ucr.edu.
While you're there, you might want to look at HLA (the high level
assembler) and "The Art of Assembly Language Programming"
Cheers,
Randy Hyde

"Dpak Cherian" <dpakch3r1an@fastmail.fm> wrote in message
news:476dbfa6.0401231513.3b3e4cbc@posting.google.com...
> in 16-bit assembly is there any way to accept numbers as input and display
them.
> btw, is there anything like cin & cout in assembly
>
> PS. I'm a complete newbie so plz excuse
>


0
Reply Randall 1/24/2004 6:03:28 AM

On Sat, 24 Jan 2004 00:33:38 +0000 (UTC), dpakch3r1an@fastmail.fm
(Dpak Cherian) wrote:

>in 16-bit assembly is there any way to accept numbers as input and display them.
>btw, is there anything like cin & cout in assembly

No way, there's no way of doing cin/cout in assembly.  Once the
compiler generates machine instructions, there is no cin/cout.
Actually, in reality there's only one GIGANTIC factor we must know
here.... What OS?????  Seeing as how you did cross-post this to
comp.lang.asm.x86, I can rule out any non-intel 16-bit processors,
hybrid 8/16-bit processors and such.... Considering that all forms of
UNIX and LINUX are 32-bit or 64-bit, I can rule out Linux as the OS,
and can rule out Windows/XP, Windows/NT.... Now I *think* I can make
it fairly safe to assume your either using GEOS Ensamble, Windows
3.1/3.0 (maybe 2.0 or 1.0), or a version of MS-DOS/compatible OS.  
With that in mind, that narrows down the scope of your answer a bit.
GEOS on the PC I only know GeoBASIC, and I don't think they sell it
any more, so I'll just say you have to find some other fool to help
you there if that's what you want.... Windows 3.0/3.1 your really up a
creak without a paddle.  What the compilers do when you have cin/cout
in windows is usually create a window and write out  text to that
window.  Doing so will mean creating a window, keeping track of the
cursor position, creating a new font, writing the text out, updating
the cursor position, etc...  Don't ask me to explain/write that....
Besides there's much more qualified people for that....  Now to the OS
I'm most qualified as a God at....  MS-DOS Compatible... (Which I'm
hoping you meant anyway....)

All MS-DOS functions are handled through INT 21h.  Grab a copy of
Ralph Brown's interrupt primer.  In it, you'll see Function 9.

Eg.


CODE SEGMENT PUBLIC 'Me'
ASSUME CS:CODE,DS:CODE,SS:None
Start:        MOV AX, CS
	  MOV DS, AX  ; DS=CS
                MOV AH, 9                         ; DOS Print String
                MOV DX, OFFSET Data1 ; Our String        
                INT    21h
                RET

Data1:  DB 'This is our string.',13,10,'$'
CODE ENDS
            END Start

The string *MUST* be terminated with a $.

For Standard Input, use AH=0Ah, DS:DX points to your buffer, which is
as follows:

1st Byte is the Maximum # bytes your buffer holds
2nd Byte is the # bytes actually read (on return)
3rd Byte onward is the actual string the user typed in.... Including
carridge return

CIN/COUT refers to Console In/Out, which in some C compilers means
direct screen writes.  For that, you get to do things the hard way....
You move the string to the screen where you want it and handle the
attribute yourself.... Some C compilers will use INT 10h and use the
character out, others will just use STDOUT....  Either way, I highly
recommend you pick up Ralph Brown's interrupt primer and read the
introduction carefully, perhaps grab A86 and read up on how the INT
instruction works and 16-bit memory is layed out...  Everyone hates it
when I recommend A86 manual, but it really does have some great
information in it.    The older Art of Assembly language I believe is
geared towards 16-bit DOS assembly, and has some libraries that
provide easier access to input/output routines, though grasping an
understanding of what the library is doing really helps....

>PS. I'm a complete newbie so plz excuse
Not knowing, but having a desire to learn is not a problem.... Wanting
us to do something for you is a problem.  And ASSUMING (as an
instructor once said) makes an ASS out of U and ME.... So just try not
to ASSUME that we know you are referring to MS-DOS or Intel, or
Windows 16-bit assembly.... And if you meant 16-bit motorola and you
cross-posted it to comp.lang.asm.x86 because you where too lazy to
check your posting before you sent it.... All I can say is you earned
any flames you get ;-)  

0
Reply John 1/24/2004 6:42:43 AM

"Brandon J. Van Every" wrote:

> I'm slightly curious why you care about 16-bit ASM in the modern day.
> Actually, I'm not curious, that's the wrong word.  I'm saying you shouldn't
> be bothering with 16-bit ASM for any reason.  32-bit is minimum.  

There are still much more 4/8 bit processors sold than 16/32/64 processors.
But even if an Intel 32 bit processor is used, a beginner always 
should start learning assembly programming in real or V86 mode and
not in protected mode. The language of the processor is the same
but the interface to the operating system (int 21 or even BIOS) is
much simpler than the Win32 interface. And you can use almost all 
32 bit instructions and addressing modes also in real/V86 mode.
The only restriction is the limit of 64k memory (without using
segmentation) which surely isn't a limitation for learning
assembly programming.

As an example a simple program which reads from stdin and writes
to stdout, converting all upper case characters to lower case.
To make it compatible with the win32 version, it uses mostly
32 bit instructions. But even then the generated executable
file size is only 109 bytes.

        @=$100
loop:   bsr.l   getc            ; get char from stdin
        cmp.l   #-1,r0          ; EOF
        bne.b   _10             ; branch if not
        moveq.l #0,-(sp)
        bsr.l   ExitProcess     ; exit program
_10:    cmp.b   #'A',r0
        blo.b   _20
        cmp.b   #'Z',r0
        bhi.b   _20
        add.b   #'a'-'A',r0
_20:    bsr.l   putc            ; write char to stdout
        br.b    loop            ; go on


putc:   movem.l r0-r7,-(sp)
        move.b  r0,_buf
        move.b  #$40,m0
        move.w  #_buf,r1
        move.w  #1,r2
        move.w  #1,r3
        trap    #$21
        movem.l (sp)+,r0-r7
        rts.l
_buf:   dc.b    0


getc:   movem.l r0-r7,-(sp)
        move.b  #$3f,m0
        move.w  #_buf,r1
        move.w  #1,r2
        eor.w   r3,r3
        trap    #$21
        bcs.b   _10
        cmp.w   r0,r2
        bne.b   _10
        movem.l (sp)+,r0-r7
        move.b  _buf,r0
        rts.l
_10:    movem.l (sp)+,r0-r7
        move.l  #-1,r0
        rts.l
_buf:   dc.b    0


ExitProcess:
        move.b  #$4c,m0
        trap    #$21


Now look at the same program in a win32 version. The main part
is identical to the above version, but the overhead is 
terrible (especially for a beginner) and the generated exe
is 1024 bytes.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; STDINOUT.mac: copy stdin to stdout and convert all upper case  ;;
;;               letter to lower case                             ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UseIdatSection=0 ; 0 if no idat section is used
UseUdatSection=0 ; 0 if no udat section is used

;#==================================================================#
;#                    Start of Headers                              #
;#==================================================================#

;       +--------------------------------------------+
;       |         Start of DOS Header                |
;       +--------------------------------------------+

                                ; DOS .EXE header
        dc.b    'MZ'            ; Magic number
        dc.w    dosfilesize\512 ; Bytes on last page of file (0->512)
        dc.w    (dosfilesize-1)/512+1           
                                ; Pages in file (Page=512 byte)
        dc.w    0               ; Relocations (nr of entries)
        dc.w    doshead_end/16  ; Size of header size in paragraphs (16 byte)
        dc.w    0               ; Minimum extra paragraphs needed
        dc.w    $ffff           ; Maximum extra paragraphs needed
        dc.w    0               ; Initial (relative) SS value (ss=load_adr+nr)
        dc.w    dosstack        ; Initial SP value
        dc.w    0               ; Checksum
        dc.w    dosmain         ; Initial IP value
        dc.w    0               ; Initial (relative) CS value (cs=load_adr+nr)
        dc.w    reloc           ; File address of relocation table
        dc.w    0               ; Overlay number
        dc.w    0,0,0,0         ; Reserved words
        dc.w    0               ; OEM identifier (for e_oeminfo)
        dc.w    0               ; OEM information; e_oemid specific
        dc.l    0,0,0,0,0       ; Reserved words
        dc.l    WinHeader       ; File address of new exe header
reloc:
doshead_end:

        @=$0
dosmain:move.w   s6,-(sp)
        move.w   (sp)+,s0
        move.w   #_text,r1
        move.b   #$09,m0
        trap     #$21
        move.w   #$4c01,r0
        trap     #$21
_text:  dc.b    'Nice to meet somebody who is still using DOS,',13,10
        dc.b    'but his program requires Win32.',13,10,'$'
        even 16       
        
dosstack=@+256          ; 256 Byte stack
dosfilesize=@+256

;       +--------------------------------------------+
;       |           End of DOS Header                |
;       +--------------------------------------------+


;       +--------------------------------------------+
;       |         Start of Windows Header            |
;       +--------------------------------------------+

        ImageBase==   $00400000
        SectionAlignment== 4096
        FileAlignment==     512

        WinHeader=@@
        @=ImageBase

                                      ; see WINNT.H for information
        dc.b   'PE',0,0               ; magic word
                                      ; _IMAGE_FILE_HEADER:
        dc.w    $014c                 ; Machine ($014c=Intel x86 processor) 
        dc.w    NumberOfSections      ; NumberOfSections
        dc.l    $36a57950             ; TimeDateStamp (seconds since  31.12.69 16:00)
        dc.l    0                     ; PointerToSymbolTable
        dc.l    0                     ; NumberOfSymbols
        dc.w    SizeOfOptionalHeader  ; SizeOfOptionalHeader
        dc.w    $010f                 ; Charcteristics

        ; 0x0001 Relocation info stripped from file.
        ; 0x0002 File is executable  (i.e. no unresolved externel references).
        ; 0x0004 Line nunbers stripped from file.
        ; 0x0008 Local symbols stripped from file.
        ; 0x0010 Agressively trim working set
        ; 0x0080 Bytes of machine word are reversed.
        ; 0x0100 32 bit word machine.
        ; 0x0200 Debugging info stripped from file in .DBG file
        ; 0x0400 If Image is on removable media, copy and run from the swap file.
        ; 0x0800 If Image is on Net, copy and run from the swap file.
        ; 0x1000 System File.
        ; 0x2000 File is a DLL.
        ; 0x4000 File should only be run on a UP machine
        ; 0x8000 Bytes of machine word are reversed.
        
        @a=@                          ; _IMAGE_OPTIONAL_HEADER
        dc.w    $010b                 ; Magic
        dc.b    5                     ; MajorLinkerVersion
        dc.b    12                    ; MinorLinkerVersion
        dc.l    SizeOfCode            ; SizeOfCode
        dc.l    SizeOfInitializedData ; SizeOfInitializedData
        dc.l    SizeOfUninitializedData ; SizeOfUninitializedData
        dc.l    winmain-ImageBase     ; AddressOfEntryPoint
        dc.l    BaseOfCode            ; BaseOfCode
        dc.l    BaseOfData            ; BaseOfData
        dc.l    ImageBase             ; ImageBase
        dc.l    SectionAlignment      ; SectionAlignment
        dc.l    FileAlignment         ; FileAlignment
        dc.w    4                     ; MajorOperatingSystemVersion
        dc.w    0                     ; MinorOperatingSystemVersion
        dc.w    0                     ; MajorImageVersion
        dc.w    0                     ; MinorImageVersion
        dc.w    4                     ; MajorSubsystemVersion
        dc.w    0                     ; MinorSubsystemVersion
        dc.l    0                     ; Win32VersionValue
        dc.l    SizeOfImage           ; SizeOfImage
        dc.l    SizeOfHeaders         ; SizeOfHeaders
        dc.l    0                     ; CheckSum
        dc.w    3                     ; Subsystem
                ; 0:  Unknown subsystem.
                ; 1:  Image doesn't require a subsystem.
                ; 2:  Image runs in the Windows GUI subsystem.
                ; 3:  Image runs in the Windows character subsystem.
                ; 5:  image runs in the OS/2 character subsystem.
                ; 7:  image run  in the Posix character subsystem.
                ; 8:  image run  in the 8 subsystem.
        dc.w    $0000                 ; DllCharacteristics
        dc.l    $00100000             ; SizeOfStackReserve
        dc.l    $00001000             ; SizeOfStackCommit
        dc.l    $00100000             ; SizeOfHeapReserve
        dc.l    $00001000             ; SizeOfHeapCommit
        dc.l    $00000000             ; LoaderFlags
        dc.l    NumberOfRvaAndSize    ; NumberOfRvaAndSize (entries
                                      ; in the data dir)

;       ..............................................
;       :      Start of Image Data Directory         :
;       ..............................................

                ; virtual address, size
        @b=@
        dc.l    0,0                     ; Export Directory
        dc.l    imp_start,imp_size      ; Import Directory
        dc.l    0,0                     ; Resource Directory
        dc.l    0,0                     ; Exception Directory
        dc.l    0,0                     ; Security Directory
        dc.l    0,0                     ; Base Relocation Table
        dc.l    0,0                     ; Debug Directory
        dc.l    0,0                     ; Description String
        dc.l    0,0                     ; Machine Value (MIPS GP)
        dc.l    0,0                     ; TLS Directory
        dc.l    0,0                     ; Load Configuration Directory
        dc.l    0,0                     ; Bound Import Directory in headers
        dc.l    iat_start,iat_size      ; Import Address Table
        dc.l    0,0                     ; 14
        dc.l    0,0                     ; 15
        dc.l    0,0                     ; 16

        NumberOfRvaAndSize   = (@-@b)/8
        SizeOfOptionalHeader = @-@a

;       ..............................................
;       :        End of Image Data Directory         :
;       ..............................................

;       ..............................................        
;       :      Start of Image Sections Header        :
;       ..............................................

        @a=@

        dc.b    '.text',0,0,0   ; name
        dc.l    VSizeOf_text    ; virtual size
        dc.l    VBaseOf_text    ; virtual address
        dc.l    FSizeOf_text    ; size of raw data
        dc.l    FBaseOf_text    ; pointer to raw data
        dc.l    0               ; pointer to relocatins        
        dc.l    0               ; pointer to line numbers
        dc.w    0               ; number of relocations
        dc.w    0               ; number of line numbers        
        dc.l    $e0000020       ; characteristics


        IF UseIdatSection
        dc.b    '.idat',0,0,0   ; name
        dc.l    VSizeOf_idat    ; virtual size
        dc.l    VBaseOf_idat    ; virtual address
        dc.l    FSizeOf_idat    ; size of raw data
        dc.l    FBaseOf_idat    ; pointer to raw data
        dc.l    0               ; pointer to relocatins
        dc.l    0               ; pointer to line numbers
        dc.w    0               ; number of relocations        
        dc.w    0               ; number of line numbers        
        dc.l    $e0000040       ; characteristics
        ENDIF
                  
        IF UseUdatSection
        dc.b    '.udat',0,0     ; name
        dc.l    VSizeOf_udat    ; virtual size
        dc.l    VBaseOf_udat    ; virtual address
        dc.l    FSizeOf_udat    ; size of raw data
        dc.l    FBaseOf_udat    ; pointer to raw data
        dc.l    0               ; pointer to relocatins
        dc.l    0               ; pointer to line numbers
        dc.w    0               ; number of relocations        
        dc.w    0               ; number of line numbers        
        dc.l    $e0000080       ; characteristics
        ENDIF

        NumberOfSections=(@-@a)/40

;      ..............................................        
;      :        End of Image Sections Header        :
;      ..............................................
        
       ; characteristics
       ; 0x00000020  // Section contains code.
       ; 0x00000040  // Section contains initialized data.
       ; 0x00000080  // Section contains uninitialized data.
       ; 0x00000200  // Section contains comments or some other type of information.
       ; 0x00000800  // Section contents will not become part of image.
       ; 0x00001000  // Section contents comdat.
       ; 0x01000000  // Section contains extended relocations.
       ; 0x02000000  // Section can be discarded.
       ; 0x04000000  // Section is not cachable.
       ; 0x08000000  // Section is not pageable.
       ; 0x10000000  // Section is shareable.
       ; 0x20000000  // Section is executable.
       ; 0x40000000  // Section is readable.
       ; 0x80000000  // Section is writeable.

;      +--------------------------------------------+
;      |           End of Windows Header            |
;      +--------------------------------------------+

        evencom FileAlignment

        SizeOfHeaders==@@

;#==================================================================#
;#                      End of Headers                              #
;#==================================================================#

;#==================================================================#
;#                     Start of Sections                            #
;#==================================================================#

;      +--------------------------------------------+
;      |         Start of .text Section             |
;      +--------------------------------------------+

FBaseOf_text==@@
VBaseOf_text==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
BaseOfCode==VBaseOf_text
@=ImageBase+VBaseOf_text


;      ..............................................        
;      :         Start of Thunk Table               :
;      ..............................................


       iat_start=@-ImageBase

USER32_thunk:
MessageBoxA::   dc.l        USER32_MessageBoxA          -ImageBase
                dc.l        0

KERNEL32_thunk:
ExitProcess::   dc.l        KERNEL32_ExitProcess        -ImageBase
GetStdHandle::  dc.l        KERNEL32_GetStdHandle       -ImageBase
ReadFile::      dc.l        KERNEL32_ReadFile           -ImageBase
WriteFile::     dc.l        KERNEL32_WriteFile          -ImageBase
                dc.l        0


       iat_size=@-ImageBase-iat_start

;      ..............................................        
;      :           End of Thunk Table               :
;      ..............................................


;      ..............................................        
;      :         Start of Import Directory          :
;      ..............................................


            imp_start==@-ImageBase

            imp:        

            dc.l    USER32_import       -ImageBase
            dc.l    0
            dc.l    0
            dc.l    USER32_name         -ImageBase
            dc.l    USER32_thunk        -ImageBase

            dc.l    KERNEL32_import     -ImageBase
            dc.l    0
            dc.l    0
            dc.l    KERNEL32_name       -ImageBase
            dc.l    KERNEL32_thunk      -ImageBase

            dc.l    0            
            dc.l    0            
            dc.l    0            
            dc.l    0            
            dc.l    0            

            imp_size==@-imp

;      ..............................................        
;      :           End of Import Directory          :
;      ..............................................



USER32_name:
            dc.b    'USER32.dll',0
            even                

USER32_import:
            dc.l    USER32_MessageBoxA          -ImageBase
            dc.l    0
            even

USER32_MessageBoxA:  
            dc.w    0
            dc.b    'MessageBoxA',0
            even        


KERNEL32_name:
            dc.b    'KERNEL32.dll',0
            even                

KERNEL32_import:
            dc.l    KERNEL32_ExitProcess        -ImageBase
            dc.l    KERNEL32_GetStdHandle       -ImageBase
            dc.l    KERNEL32_ReadFile           -ImageBase
            dc.l    KERNEL32_WriteFile          -ImageBase
            dc.l    0
            even

KERNEL32_ExitProcess:
            dc.w    0
            dc.b    'ExitProcess',0
            even
KERNEL32_GetStdHandle:
            dc.w    0
            dc.b    'GetStdHandle',0
            even
KERNEL32_ReadFile:
            dc.w    0
            dc.b    'ReadFile',0
            even
KERNEL32_WriteFile:
            dc.w    0
            dc.b    'WriteFile',0
            even





;      ..............................................        
;      :         Start of Code                      :
;      ..............................................


        label_block
        seg32


winmain::

loop:   bsr.l   getc            ; get char from stdin
        cmp.l   #-1,r0          ; EOF
        bne.b   _10             ; branch if not
        moveq.l #0,-(sp)
        jsr.l   (ExitProcess)   ; exit program
_10:    cmp.b   #'A',r0
        blo.b   _20
        cmp.b   #'Z',r0
        bhi.b   _20
        add.b   #'a'-'A',r0
_20:    bsr.l   putc            ; write char to stdout
        br.b    loop            ; go on




putc:   move.l  r0,-(sp)
        move.b  r0,_buf
        eor.l   r0,r0
        add.l   _handle,r0
        bne.b   _10
        moveq.l #-11,-(sp)
        jsr.l   (GetStdHandle)
        move.l  r0,_handle
_10:    moveq.l #0,-(sp)
        move.l  #_count,-(sp)
        moveq.l #1,-(sp)
        move.l  #_buf,-(sp)
        move.l  r0,-(sp)
        jsr.l   (WriteFile)
        or.l    r0,r0
        bne.b   _20
_30:    moveq.l #0,-(sp)        
        move.l  #_text,-(sp)
        move.l  #_text,-(sp)
        moveq.l #0,-(sp)
        jsr.l   (MessageBoxA)
        moveq.l #0,-(sp)
        jsr.l   (ExitProcess)
_20:    cmp.l   #1,_count
        bne.b   _30
        move.l  (sp)+,r0
        rts.l
                        
_buf:   dc.b    0
_text:  dc.b    'write error',0
        even4
_handle:dc.l    0
_count: dc.l    0


getc:   eor.l   r0,r0
        add.l   _handle,r0
        bne.b   _10
        moveq.l #-10,-(sp)
        jsr.l   (GetStdHandle)
        move.l  r0,_handle
_10:    moveq.l #0,-(sp)
        move.l  #_count,-(sp)
        moveq.l #1,-(sp)
        move.l  #_buf,-(sp)
        move.l  r0,-(sp)
        jsr.l   (ReadFile)
        or.l    r0,r0
        bne.b   _20
        moveq.l #0,-(sp)        
        move.l  #_text,-(sp)
        move.l  #_text,-(sp)
        moveq.l #0,-(sp)
        jsr.l   (MessageBoxA)
        moveq.l #0,-(sp)
        jsr.l   (ExitProcess)
_20:    movu.bl _buf,r0
        cmp.l   #1,_count
        beq.b   _30
        move.l  #-1,r0
_30:    rts.l
                        
_buf:   dc.b    0
_text:  dc.b    'read error',0
        even4
_handle:dc.l    0
_count: dc.l    0


;      ..............................................        
;      :           End of Code                      :
;      ..............................................

VSizeOf_text==@-Imagebase-VBaseOf_text
        @a=@
        evencom FileAlignment
        @=@a
        
FSizeOf_text==@@-FBaseOf_text
SizeOfCode==FSizeOf_text


;      +--------------------------------------------+
;      |           End of .text Section             |
;      +--------------------------------------------+


;      +--------------------------------------------+
;      |          Start of .idat Section            |
;      +--------------------------------------------+


FBaseOf_idat==@@
VBaseOf_idat==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
BaseOfData==VBaseOf_idat
@=ImageBase+VBaseOf_idat

; Insert initialized variables here (and set UseIdatSection=1
; at the top of this file). Because the code section is set
; r/w-able, you can put initialized variables also into the
; code section.

; var1:    dc.l    0
; var2:    dc.l    $12345678

VSizeOf_idat==@-Imagebase-VBaseOf_idat
        @a=@
        evencom FileAlignment
        @=@a
FSizeOf_idat==@@-FBaseOf_idat

;      +--------------------------------------------+
;      |            End of .idat Section            |
;      +--------------------------------------------+

SizeOfInitializedData==FSizeOf_idat


;      +--------------------------------------------+
;      |          Start of .udat Section            |
;      +--------------------------------------------+


FBaseOf_udat==@@
VBaseOf_udat==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment
@=ImageBase+VBaseOf_udat

; Insert uninitialized variables here (and set UseUdatSection=1
; at the top of this file). Because the code section is set
; r/w-able, you can put uninitialized variables also at the END
; of the code section.

; buf1:    blk.l    10
; buf2:    blk.l   200

VSizeOf_udat==@-Imagebase-VBaseOf_udat
        @a=@
        evencom FileAlignment
        @=@a
FSizeOf_udat==@@-FBaseOf_udat

;      +--------------------------------------------+
;      |            End of .udat Section            |
;      +--------------------------------------------+

SizeOfUninitializedData==VSizeOf_udat
SizeOfImage==(@-ImageBase+SectionAlignment-1)/SectionAlignment*SectionAlignment


;#==================================================================#
;#                       End of Sections                            #
;#==================================================================#

0
Reply Herbert 1/24/2004 9:00:59 AM

"Herbert Kleebauer" <klee@unibwm.de> wrote in message
news:40123268.75F447@unibwm.de...
<snip>
> But even if an Intel 32 bit processor is used, a beginner always
> should start learning assembly programming in real or V86 mode and
> not in protected mode. The language of the processor is the same
> but the interface to the operating system (int 21 or even BIOS) is
> much simpler than the Win32 interface. And you can use almost all
> 32 bit instructions and addressing modes also in real/V86 mode.
> The only restriction is the limit of 64k memory (without using
> segmentation) which surely isn't a limitation for learning
> assembly programming.
<snip>

Making an interrupt is simpler than call _getc or call _malloc? I think not.

32-bit code has the simplicity of not having to use specific registers in
its addressing modes. Also, flat memory is far less confusing than segmented
memory. Moreover, debugging Win32/Linux code is a lot simpler. I have done
both. I do not miss the days of DOS.

-Matt


0
Reply Matt 1/24/2004 9:49:43 AM

"Dpak Cherian" <dpakch3r1an@fastmail.fm> wrote in message
news:476dbfa6.0401231513.3b3e4cbc@posting.google.com...
> in 16-bit assembly is there any way to accept numbers as input and display
them.
> btw, is there anything like cin & cout in assembly

Everything eventually becomes machine code. While there are no simple
statements in assembly that do what cin & cout do, there are none in C/C++
either. When you write "cout << endl;", you are making a function call. The
same can be done in assembly. I would recommend looking at the code your
compiler produces. If you use GCC, try this:

g++ -S input.cpp -o input.s

-Matt


0
Reply Matt 1/24/2004 9:58:15 AM

"Matt Taylor" <para@tampabay.rr.com> wrote in message
news:ZbrQb.94346$873.1662086@twister.tampabay.rr.com...
> "Dpak Cherian" <dpakch3r1an@fastmail.fm> wrote in message
> news:476dbfa6.0401231513.3b3e4cbc@posting.google.com...
> > in 16-bit assembly is there any way to accept numbers as input and
display
> them.
> > btw, is there anything like cin & cout in assembly
>
> Everything eventually becomes machine code. While there are no simple
> statements in assembly that do what cin & cout do, there are none in C/C++
> either. When you write "cout << endl;", you are making a function call.
The
> same can be done in assembly. I would recommend looking at the code your
> compiler produces. If you use GCC, try this:
>
> g++ -S input.cpp -o input.s
>
> -Matt

Well, you *can* have cout and cin in your DOS assembly code.
All you need is the appropriate library code and macro support.
Here's a following sample program I created with MASM v6.11a
(the suffix is important here) using the UCR Standard Library v2.0:

var
   enum colors,<red,green,blue>
   colors c1, c2

endvar

Main proc

   mov ax, dseg
   mov ds, ax
   mov es, ax

   MemInit
   InitExcept
   EnableExcept
   finit

   try

      cout "Enter two colors:"
      cin c1, c2
      cout "You entered ",c1," and ",c2,nl

      .if c1 == red

         cout "c1 was red"

      .endif



     except $Conversion

      cout "Conversion error occured",nl

     except $Overflow

      cout "Overflow error occured",nl

   endtry
   CleanUpEx

   ExitPgm ;DOS macro to quit program.

Main endp


The only problem with this code is the fact that the
macro package in the UCR Standard Library v2.0
exploited some "features" in MASM v6.11a that
went away when MASM v6.11d came along.
It was exactly this kind of trouble (plus the fact that
the macros weren't very robust when there was a
syntax error in their use) that convinced me to write
the High-Level Assember.

Of course, in HLA (the High Level Assembler), the
macro facilities are a bit better and you can do all
kinds of neat things concerning I/O.  E.g.,

program demo;
#include( "stdlib.hhf" )
var
    i    :int32;
    j    :uns32;
begin demo;

    stdout.put( "Enter values for i & j:" );
    try

        stdin.get( i, j );
        stdout.put( "You entered ", i, " and ", j, nl );

      anyexception

        stdout.put( "Error inputing the numeric values" nl );

    endtry;

end demo;

Yes, having a nice set of macros in assembly language
can make I/O just as easy as a high-level language. This
is much better than INT 21h or API calls.

The drawback, of course, is that HLA is 32-bit based
and runs under Win32 or Linux, not DOS (then again,
some consider the fact that they don't have to learn
an obsolete OS API set to be an advantage). The
advantage is that this code compiles and runs unchanged
on either Linux or Windows - something you don't get
when you make OS API calls.
Cheers,
Randy Hyde



0
Reply Randall 1/24/2004 4:54:59 PM

Herbert Kleebauer <klee@unibwm.de> wrote in news:40123268.75F447@unibwm.de:

> But even if an Intel 32 bit processor is used, a beginner always 
> should start learning assembly programming in real or V86 mode and
> not in protected mode.

Could you tell me in few words what a different in using real/protected 
mode or V86 (?). What V86 is?

-- 
pozdr.  Dygi [GG 1027078]
dygimail(at)poczta(dot)fm

0
Reply Mr 1/24/2004 5:59:38 PM

Mr Dygi wrote:
> 
> > But even if an Intel 32 bit processor is used, a beginner always
> > should start learning assembly programming in real or V86 mode and
> > not in protected mode.
> 
> Could you tell me in few words what a different in using real/protected
> mode or V86 (?). What V86 is?

Maybe Beth can do this. But in order to learn assembly
programming, you have to read the processor manual anyhow:

http://developer.intel.com/design/pentium4/manuals/245471.htm
0
Reply Herbert 1/24/2004 9:23:32 PM

Dpak Cherian wrote:
> in 16-bit assembly is there any way to accept numbers as input and
display them.
> btw, is there anything like cin & cout in assembly
>
> PS. I'm a complete newbie so plz excuse

Theoretical bit:

There isn't anything like "cin" / "cout" in assembly; Assembly
language is simply a human-readable form of the CPU's actual
"language"...the _real_ instructions that the CPUs processes...there's
no "abstraction" applied, _except_ for re-writing it as human-readable
text (the CPU actually sees just "binary numbers" :) so that _people_
can actually _use_ it more happily and comfortably than sifting
through tons of numbers all day long...

High-level languages, like C++, "abstract" away from the actual
machine-specifics and are more "problem-orientated" than
"machine-orientated" (though, actually, as an aside, C / C++ is the
HLL that tends to do this _least_..."cin" / "cout" are, of course,
merely "standard additions" in the "standard library" with C++ and, in
fact, even C++ doesn't really have these things "built-in"
either...but if you didn't "#include" the right header file then even
C++ doesn't actually have "cin / cout" as _part of the language_
either...it has them as "standard additions" in the packaged libraries
that usually come along with a C++ compiler :)...so, they like to
provide these kinds of things to help a programmer with their
"problem"...

Assembly language, though, is "machine-orientated"...basically because
assembly language _IS_ the machine, so to speak...or, at least, it's a
human-readable equivalent to the machine instructions that will
finally go through the CPU (i.e. it looks different but, to all
intents and purposes, assembly language is equivalent to machine code
for most of our purposes)...unlike high-level languages, which
"abstract" away from the machine and move more towards the so-called
"problem domain" (defining things in terms of the problem itself
rather than in the terms the machine actually sees things), assembly
language by its nature, _reflects_ the true nature of the CPU and the
system...

And in hardware terms, the keyboard and monitor (for input and output)
are _separate_ items from the CPU...hence, the CPU has no "keyboard"
or "monitor" instructions because those are separate hardware
devices...in assembly language, you control the _CPU_ by talking
directly to it...all other hardware is controlled by instructing the
CPU to "talk" to the other hardware...it's done "indirectly" via the
CPU...there are no "keyboard" instructions but there are instructions
to tell the CPU to send data to other hardware and mechanisms for
accepting data back...or, alternatively, there are instructions to
call into OS or BIOS services which can do the actual low-level
hardware interfacing on behalf of the application...usually used to
provide "portable" access to hardware or simply because they are
easier, comparable to calling C functions like "printf" to do the
same...the following gives a basic practical "starting point" for
looking further into this subject, by covering some of the basic DOS
I/O functions...hardly "comprehensive" but intended to give a basic
set of illustrative examples in how to go about this, from which you
can Hopefully get a reasonable idea of what's going on to be able to
search through "HelpPC" or Ralf Brown's list or some other resources
yourself and being to know what to do and what to expect...

Practical bit:

[ As you've not specified OS or assembler, then the following example
code is for DOS using MASM / TASM syntax, as the most likely
combination you'd probably need :) ]

1. Download "HelpPC" and unzip it somewhere useful on your hard drive:

http://cs.nyu.edu/~yap/classes/machineOrg/helppc/helppc21.zip

2. Run "HelpPC.com"...

3. Select the "Interrupt Services" menu option...

4. Select the "DOS functions" item in the next menu...

5. The DOS functions of interest (that is, that I actually go on with
examples in this post...they are all "interesting" for some purpose
and you might want to look them over and see if you can get them to
work on your own, once you've got a "handle" on how these basic ones
work to give you the basic pattern :) in this list are:

High-level functions:
    INT 21h, AH = 09h: Print String
    INT 21h, AH = 0Ah: Buffered Keyboard Input (with echo)

[ These functions deal with complete strings under DOS's control; Easy
to use but can't be "customised" much so you have to accept however
DOS deals with the user I/O... ]

Low-level functions:
    INT 21h, AH = 01h: Keyboard Input with Echo
    INT 21h, AH = 02h: Display Output

[ These functions only deal with I/O of individual characters; Can be
called repeatedly with your own code managing the individual
characters into complete strings itself...useful if you need
functionality that's not provided by the "high-level" functions
above - e.g. printing strings with a "$" sign inside them or providing
"non-standard" input facilities - because you can take more control by
using individual character I/O and handling the rest yourself in your
own code :) ]

5a. The DOS "Print String" function (INT 21h, AH = 09h) prints out a
string of characters, pointed to by DS:DX, up to the first dollar sign
("$") it finds in that string, to the "stdout" device...

Example of use (MASM / TASM syntax):

Print.asm
---------------- 8< ------------------

         .model tiny

         .data

MyString db    "Hello, World!$"

         .code

         org    100h

         ; Print string passing the
         ; address of our "$"-terminated
         ; string in DS:DX...
         ;
 _start: mov    ah, 09h
         mov    dx, offset MyString
         int    21h

         ; Exit back to DOS prompt
         ;
         mov    ah, 4Ch
         int    21h

         end    _start

---------------- >8 ------------------

Note that the address of the string is DS:DX, not just DX...but the DS
segment register is automatically pointing to the right place in a
...COM file, so it doesn't need to be set in this example...

As it writes to "stdout", which is the console by default, but this
may be "redirected" using the standard DOS methods...for example,
"Print.com > Hello.txt" will redirect the output of the program into
the "Hello.txt" file by using the ">" DOS command to change "stdout"
to a file...

5b. The DOS "Buffered Keyboard Input" function (INT 21h, AH = 0Ah)
accepts the address to a specially-formatted "buffer" in the DS:DX
register pair...and then DOS takes over the control of input until the
ENTER key is pressed (maximum buffer size: 255 bytes, minimum buffer
size: 1 byte :)...input is read from "stdin" and the function won't
accept more characters than is specified as the "max character
count"...DOS editing keys are available with the function...

The buffer is of the following format (use fixed pitch font to view):

+-------+-------+---------------------------------------+
|  Max  | Count | Buffer (N bytes)                      |
+--/|\--+--/|\--+--/|\----------------------------------+
    |       |       |
    |       |       +--- Input buffer (N bytes)
    |       |            (returns actual input when input complete)
    |       |
    |       +----------- Number of characters returned (byte)
    |                    (returned by function when input complete)
    |
    +------------------- Maximum number of characters to be read
(byte)
                         (specified to function to define the maximum
                          amount of characters in buffer; That is,
this
                          value defines the size of "N bytes" to the
                          function and is placed in the buffer
_before_
                          calling the function)


Example of usage (MASM / TASM syntax):

BufInput.asm:
---------------- 8< ------------------

               .model tiny

MAX_CHARACTERS equ    12

               .data

        Buffer db     MAX_CHARACTERS
               db     ?
               db     MAX_CHARACTERS dup (?)

               .code

               org    100h

               ; Call buffered keyboard input
               ; passing the address of our
               ; buffer in DS:DX...
               ;
       _start: mov    ah, 0Ah
               mov    dx, offset Buffer
               int    21h

               ; Exit back to DOS prompt...
               ;
               mov     ah, 4Ch
               int     21h

               end    _start

---------------- >8 ------------------

Note that the address of the string is DS:DX, not just DX...but the DS
segment register is automatically pointing to the right place in a
...COM file, so it doesn't need to be set in this example...

Input is taken from "stdin" and output is written to "stdout"...either
or both may be "redirected" using the standard DOS mechanisms...for
example, "bufinput > input.txt" will "echo" the input to the
"input.txt" file (input won't be visible as it's gone to the
file)...and then "bufinput < input.txt" will read the input from the
"input.txt" file and redirect it to the screen (previous input can now
be read back out of the file and "echoed" onto the screen)...and then
"bufinput < input.txt > output.txt" will read in from "input.txt" and
echo the input to "output.txt" (effectively, just copying it from one
file to the other :)...

[ Be careful of this redirection in that if you supply a file that
doesn't have a proper terminator, the DOS function simply sits waiting
for one, which will never come because it's not in the file...and
pressing the keyboard ENTER is useless because, now that it's
"redirected", the program isn't looking to the keyboard for input
anymore so never gets the message...and, therefore, the program waits
forever :( ]

5c. The DOS "Display Output" function (INT 21h, AH = 02h) simply
prints out the character specified in the DL register to "stdout"...

Example of usage (MASM / TASM syntax):

Print2.asm:
---------------- 8< ------------------

            .model tiny

            .data

   MyString db    "Micro$oft $uck$!", 0

            .code

            org    100h

            ; Call custom "Print" routine
            ; passing address of string in
            ; DS:SI...
            ;
    _start: mov    si, offset MyString
            call   Print

            ; Exit back to DOS prompt...
            ;
            mov    ah, 4Ch
            int    21h

            ; Print:
            ;
            ;    DS:SI = offset to zero-terminated ASCII string
            ;
     Print: mov    ah, 02h         ; Select DOS "Display output"
function
  NextChar: mov    dl, [ si ]      ; Grab byte from SI
            cmp    dl, 00h         ; Have we reached end of string?
            je     EndOfPrint      ; Yes, then jump out of loop
            int    21h             ; Print character to "stdout"
            inc    si              ; Increment SI to move to next
character
            jmp    NextChar
EndOfPrint: ret

            end    _start

---------------- >8 ------------------

Note how I've created a custom "Print" routine using this "low-level"
function that uses a zero byte to specify the end of the string,
rather than DOS's usual "$" terminator in their "high-level" print
string function...the string to be printed has been suitably decorated
with plenty of "$" signs to demonstrate this (apologies for to
Microsoft fans ;)...

Of course, you need not write any "custom" routine this way (or at
all, even ;) and you can do anything you like...that is the beauty of
these "low-level" DOS functions in comparison to the "high-level"
ones...this function just spits out a character to "stdout" and
nothing else...it's up to your own code to use this function how you
see fit...for clever and devious purposes, no doubt ;)...

Another possibility, for example, is to use Pascal-like strings where
the first byte specifies the size of the string (and isn't printed)
and there isn't a "terminator" on the string at all (similar to that
"buffered input" function earlier, in a sense...except there's only a
single "max" figure because a "count of characters input" doesn't make
sense for an output-only function :)...

Alternative example of usage (MASM / TASM syntax):

Pascal.asm:
---------------- 8< ------------------

             .model tiny

             .data

    MyString db    22
             db    "A Pascal-style string!"

             .code

             org    100h

             ; Call custom "PascalPrint"
             ; routine passing address of
             ; Pascal-style string in
             ; DS:SI...
             ;
     _start: mov    si, offset MyString
             call   PascalPrint

             ; Exit back to DOS prompt...
             ;
             mov    ah, 4Ch
             int    21h

             ; PascalPrint:
             ;  DS:SI = offset to zero-terminated ASCII string
             ;
PascalPrint: mov    ah, 02h      ; Select DOS "Display output"
function
             mov    cl, [ si ]   ; Grab "count of characters" into CL
             inc    si           ; Advance to start of actual string
   NextChar: mov    dl, [ si ]   ; Grab character from string
             int    21h          ; Print it to "stdout"
             inc    si           ; Advance to next character
             dec    cl           ; Decrement count
             jnz    NextChar     ; Jump back to print next character
if
                                 ; not at end of string yet
             ret

             end    _start

---------------- >8 ------------------

This shows how, though the "low-level" functions don't offer as much
functionality, this is actually useful for creating "custom" print
routines...

Note, output can be redirected - just as before - using the DOS ">"
mechanism...for example, "Pascal > Pascal.txt" writes the string to
the file "Pascal.txt"...

5d. The DOS "Keyboard Input with Echo" function (INT 21h, AH = 01h)
waits for a character to be input on "stdin" and then "echoes" that
character to "stdout"...

Example of usage (MASM / TASM syntax):

Input.asm:
---------------- 8< ------------------

               .model tiny

MAX_CHARACTERS equ    12

               .data

        Buffer db     MAX_CHARACTERS
               db     MAX_CHARACTERS dup (?)

               .code

               org    100h

       _start: mov    di, offset Buffer
               call   Input

               ; Exit back to DOS prompt...
               ;
               mov    ah, 4Ch
               int    21h

               ; Input:
               ;
               ;   DS:DI = offset to input buffer
               ;           (first byte specifies size)
               ;
        Input: mov    ah, 01h       ; Select DOS "Input with echo"
function
               mov    cl, [ di ]    ; Grab size of buffer into CL (max
size)
               mov    ch, cl        ; Copy into CH (current count)
               inc    di            ; Advance to start of actual
buffer
     NextChar: int    21h           ; Input character from "stdin"
               cmp    al, 0Dh       ; Is it ENTER?
               je     EndOfInput    ; Yes, then terminate early
               cmp    al, 08h       ; Is it backspace?
               jne    CarryOn       ; No, then skip over backspace
processing

               cmp    ch, cl        ; Are we at the start of the
buffer?
               je     NextChar      ; Yes, ignore backspace as we
can't go back
                                    ; before the beginning of the
buffer
               dec    di            ; Move back a character in the
buffer
               inc    ch            ; Increment count back up
               mov    ah, 02h       ; Select DOS "display output"
               mov    dl, 20h       ; A space to clear old character
               int    21h           ; Print it!
               mov    dl, 08h       ; A backspace character moves left
                                    ; (non-destructive)
               int    21h           ; Print it!
               mov    ah, 01h       ; Restore DOS "input with echo"
function
               jmp    NextChar      ; Jump to get next character

      CarryOn: mov    [ di ], al    ; Store input into buffer
               inc    di            ; Advance to next character in
buffer
               dec    ch            ; Decrement count of characters
               jnz    NextChar      ; While there's still room in
buffer,
                                    ; do it all again
   EndOfInput: ret

               end    _start

---------------- >8 ------------------

This custom "input" routine is a little bit more complicated than the
others so far, due to the unique problem of the backspace character
(allowing the last character - _IF_ there's a last character - to be
"undone" :)...to be honest, this _isn't_ the best input routine you'll
ever see...but input is always inherently a little more complicated
because the user could type practically anything and we have to
account for it all...I've bothered to deal with the "backspace" key to
give you an appreciation of what I mean by the added complexity just
this one "undo" key adds to the input routine (we now need _two_
"count" variables - in CH and CL - to handle the "special case" of
backspace when the buffer is actually empty, which, of course, should
just be ignored as things could go dreadfully, dreadfully wrong if you
allowed a user to backspace passed the beginning of the buffer! ;)...

I make no guarantees about the "redirection" - because I didn't write
it taking that into account - but I just ran a simple test or two and
it _seemed_ to work okay...it's probably better NOT to use the "echo"
input DOS function, more generally, for this...but something like
"input without echo" (INT 21h, AH = 07h), which works just like this
function _without_ the "echo" to "stdout", though...and then use
"display output" (INT 21h, AH = 02h) to only print things that are
valid, if you need better control over that...

Because though you may not see it _visibly_ when you look at the
output of a "redirected" file (as the backspace character is being
_performed_ as part of the output of the file :), if you put it into a
hex viewer, you can actually see "20h 08h" (space backspace...the
"hack" used to make the input look right on the screen by wiping out
the old characters with a space when you tap backspace) characters in
the output file(!!)...which would _look_ okay (and the actual contents
of the buffer will be okay too, so they'd be no problems with the
variables inside the program :) but any comparison of the redirected
"Hello, world" to "Hello(space backspace)o, world" would clearly not
give a "match"...this problem, though, won't effect the program at all
when things aren't redirected...the problem is basically that
"backspace" literally moves backwards and wipes things out on the
screen, as we want, but just gets written to a _file_ like any other
character when redirected...this is a particularly tricky
problem...perhaps, simply, don't "redirect" any of the input (don't
write to "stdout") but use some "direct console" output function which
_forces_ things onto the screen without redirection and then "echo"
out the _finished_ input when ENTER is pressed...

Like I was saying, input - because the user is permitted to hit _any_
key they like on the keyboard at any point (even if it's really
annoying that they are doing silly things like trying to backspace
passed the start of the buffer, silly users! ;) - is an inherently
more complicated problem...I've given a "taste" of how to go about
solving these types of problems in the example but don't take the
example above as "role model" code to "cut and paste" into other
programs...it's "purely illustrative" because even _I_ wouldn't trust
that quick and nasty "hack" with any important user input, anyway
;)...

The benefit, of course, of the "low-level" input function over the
"high-level" one is much the same as it was with the output
functions...you get better "control" over input and can write custom
input routines...you could, for instance, use these functions to
create an input routine that only accepts hex characters or decimal
floating-point numbers (giving a "beep" if something invalid is typed
;) or that allows using the TAB key for moving around between "fields"
in a "form" (pretending that you're in a GUI...although, that makes
the already complicated "input" problem even more confusing because
you've got to handle multiple input fields at the same time and, at
the drop of a hat, allow the user to move back and forth
between...but, if you want real "user-friendliness" people are so used
to this ability from GUIs that anything less tends to kind of
"disappoint" your users ;) or whatever...

Of course, now that you've downloaded the handy "HelpPC" program,
which neatly divides up lots of ASM, DOS and BIOS stuff into nice
menus, you can just "browse" and try out code using the functions and
stuff...see what happens...

You can also grab Ralf Brown's Interrupt List from:

http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html

Which is even more comprehensive (but, thus, a little more difficult
to search than "HelpPC" :) and is indispensable if you're programming
in DOS...

Beth :)


0
Reply Beth 1/24/2004 11:00:50 PM

Herbert Kleebauer wrote:
> "Brandon J. Van Every" wrote:
> 
> 
>>I'm slightly curious why you care about 16-bit ASM in the modern day.
>>Actually, I'm not curious, that's the wrong word.  I'm saying you shouldn't
>>be bothering with 16-bit ASM for any reason.  32-bit is minimum.  
> 
> 
> There are still much more 4/8 bit processors sold than 16/32/64 processors.

I'd like a citation for this claim. Are seriously tiny embedded systems 
truly that common?

> But even if an Intel 32 bit processor is used, a beginner always 
> should start learning assembly programming in real or V86 mode and
> not in protected mode.

Should all new drivers start out with a Model-T, too? Or all new pilots 
start off with a biplane?

No, I simply cannot agree with this statement. It's wrong, and will lead 
to scaring off more people from assembly than is really needed. Intel 
botched the 16-bit generation completely, and nothing can convince me 
that it's better to start with that generation of chips (or an emulation 
thereof).

> The language of the processor is the same
> but the interface to the operating system (int 21 or even BIOS) is
> much simpler than the Win32 interface.

That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly 
programming is for Linux, and Linux has a DOS-like interrupt-driven 
kernel interface, but it's much more convenient simply because you don't 
need to beat your head against a wall simply to do things like forking.

(Plus, in Linux you can use libc and all of the other C libraries your 
system comes with. Which is damned simpler than reinventing the wheel, 
especially for new programmers, not to mention giving new assembly 
programmers experience in a very valuable area: interfacing with C code, 
either calling it or being called by it.)

Besides, I do write 32-bit code for DOS. I target FreeDOS, but MS-DOS 
3.x and later all ran on 32-bit chips.

In short, wanting to use a specific OS and/or API style (even one as 
ancient as DOS) is no reason to stick with 16-bit Intel chips.

> And you can use almost all 
> 32 bit instructions and addressing modes also in real/V86 mode.

Then why, pray tell, bother with V86 at all? Why not just go 32-bit all 
the way and forget about things like segments? (OK, 32-bit chips have 
segments. 4 Gibibyte segments. And if you need more RAM than that, why 
the hell are you writing in assembly?)

> The only restriction is the limit of 64k memory (without using
> segmentation) which surely isn't a limitation for learning
> assembly programming.

I disagree: It's a rationalization for using a broken system, and it 
will cripple new assembly programmers until they finally move on to 
semi-modern chips. 4 Gibibytes seems tiny now that 64-bit chips are 
coming down from Mount Server, but 4 Gibibytes is more than enough for 
small programs at the moment. 64 Kibibytes /is not/.

> 
> As an example a simple program which reads from stdin and writes
> to stdout, converting all upper case characters to lower case.
> To make it compatible with the win32 version, it uses mostly
> 32 bit instructions. But even then the generated executable
> file size is only 109 bytes.

Executable size? Dick-waving nonsense. Blocks on a hard drive are larger 
than that. You gain nothing by stripping the binary to less than one or 
two Kibibytes.

> 
>         @=$100
> loop:   bsr.l   getc            ; get char from stdin
>         cmp.l   #-1,r0          ; EOF
>         bne.b   _10             ; branch if not
>         moveq.l #0,-(sp)
>         bsr.l   ExitProcess     ; exit program
> _10:    cmp.b   #'A',r0
>         blo.b   _20
>         cmp.b   #'Z',r0
>         bhi.b   _20
>         add.b   #'a'-'A',r0
> _20:    bsr.l   putc            ; write char to stdout
>         br.b    loop            ; go on
> 
> 
> putc:   movem.l r0-r7,-(sp)
>         move.b  r0,_buf
>         move.b  #$40,m0
>         move.w  #_buf,r1
>         move.w  #1,r2
>         move.w  #1,r3
>         trap    #$21
>         movem.l (sp)+,r0-r7
>         rts.l
> _buf:   dc.b    0
> 
> 
> getc:   movem.l r0-r7,-(sp)
>         move.b  #$3f,m0
>         move.w  #_buf,r1
>         move.w  #1,r2
>         eor.w   r3,r3
>         trap    #$21
>         bcs.b   _10
>         cmp.w   r0,r2
>         bne.b   _10
>         movem.l (sp)+,r0-r7
>         move.b  _buf,r0
>         rts.l
> _10:    movem.l (sp)+,r0-r7
>         move.l  #-1,r0
>         rts.l
> _buf:   dc.b    0
> 
> 
> ExitProcess:
>         move.b  #$4c,m0
>         trap    #$21

I notice you /aren't even using 8088 opcodes/. Post-increment indexing 
modes? I guess it's the 68000, if it's a microprocessor, but it could 
(possibly) be a PDP or a VAX.

I'm aware that this was cross-posted to alt.lang.asm. But why would you 
hype V86 and other Intel things if your code wasn't even going to be for 
Intel chips?

-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/25/2004 2:17:44 AM

 "August Derleth" <see@sig.now> wrote in message
news:XWEQb.6301$dF4.1203@fe02.usenetserver.com...
<snip>
> > The language of the processor is the same
> > but the interface to the operating system (int 21 or even BIOS) is
> > much simpler than the Win32 interface.
>
> That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly
> programming is for Linux, and Linux has a DOS-like interrupt-driven
> kernel interface, but it's much more convenient simply because you don't
> need to beat your head against a wall simply to do things like forking.

What is true for Linux is also true for Win32. System calls are done via
interrupts and are quite convenient. Most Win32 functions aren't horribly
daunting, and it is also possible to call the C runtime functions which are
probably more familiar to some.

<snip>
> >         @=$100
> > loop:   bsr.l   getc            ; get char from stdin
> >         cmp.l   #-1,r0          ; EOF
> >         bne.b   _10             ; branch if not
> >         moveq.l #0,-(sp)
> >         bsr.l   ExitProcess     ; exit program
> > _10:    cmp.b   #'A',r0
> >         blo.b   _20
> >         cmp.b   #'Z',r0
> >         bhi.b   _20
> >         add.b   #'a'-'A',r0
> > _20:    bsr.l   putc            ; write char to stdout
> >         br.b    loop            ; go on
> >
> >
> > putc:   movem.l r0-r7,-(sp)
> >         move.b  r0,_buf
> >         move.b  #$40,m0
> >         move.w  #_buf,r1
> >         move.w  #1,r2
> >         move.w  #1,r3
> >         trap    #$21
> >         movem.l (sp)+,r0-r7
> >         rts.l
> > _buf:   dc.b    0
> >
> >
> > getc:   movem.l r0-r7,-(sp)
> >         move.b  #$3f,m0
> >         move.w  #_buf,r1
> >         move.w  #1,r2
> >         eor.w   r3,r3
> >         trap    #$21
> >         bcs.b   _10
> >         cmp.w   r0,r2
> >         bne.b   _10
> >         movem.l (sp)+,r0-r7
> >         move.b  _buf,r0
> >         rts.l
> > _10:    movem.l (sp)+,r0-r7
> >         move.l  #-1,r0
> >         rts.l
> > _buf:   dc.b    0
> >
> >
> > ExitProcess:
> >         move.b  #$4c,m0
> >         trap    #$21
>
> I notice you /aren't even using 8088 opcodes/. Post-increment indexing
> modes? I guess it's the 68000, if it's a microprocessor, but it could
> (possibly) be a PDP or a VAX.

More likely someone took PDP/VAX as a starting point and grafted x86 onto
it. The pre-decrement and post-increment indexing correspond to push/pop
instructions. The trap mneumonic replaces the int mneumonic. Other analogues
are apparent as well (such as DOS functions being called).

-Matt


0
Reply Matt 1/25/2004 3:53:18 AM

August Derleth wrote:
> Herbert Kleebauer wrote:

> > But even if an Intel 32 bit processor is used, a beginner always
> > should start learning assembly programming in real or V86 mode and
> > not in protected mode.
> 
> Should all new drivers start out with a Model-T, too? 

I didn't speak of an ancient 8086 processor. Even the newest x86 processor
supports the three modes: real/V86/protected mode. And you can use the 
32 bit instructions and all the 32 bit addressing modes in any of this
three modes. So it doesn't matter at all which of this modes you use to
LEARN assembly programing. But it is important to use an operating 
system with a simple interface so you can concentrate on the language
of the processor and don't have to spend much more time with the OS 
interface than with the processor instructions. And the int21
interface is much easier to use (and still supported in the newest
MS operating systems for V86 mode) than the Win32 interface.

Now to your example, how to learn to drive a car. Nobody says you
should use a Model-T, use the a modern car (X86). But do you think a
beginner should start in the rush hour in the streets of New York
(Windows interface)? Wouldn't it be much better to use a street
without public traffic ("DOS", which doesn't really mean DOS,
but the int21 interface for v86 programs in Windows). Then you
can concentrate on your car and needn't to worry about all
the other things happening on the streets of NY. Maybe this
empty street is only a few miles (64 kbyte) instead of the 
hundreds of miles of streets in NY (4 Gbyte), but that is enough
to learn all about your car. And once you are familiar with your
car you can start to drive through NY.
 
> No, I simply cannot agree with this statement. It's wrong, and will lead
> to scaring off more people from assembly than is really needed. Intel
> botched the 16-bit generation completely, and nothing can convince me
> that it's better to start with that generation of chips (or an emulation
> thereof).

Sorry, but I don't understand how a easy to use OS interface
can scare off people. If you look at a piece of code without
an OS call, you can't decide if this is code for V86 or
protected mode. V86 is not only the emulation of an 8086, it
supports the same 32 bit addressing modes as protected mode.


> > The language of the processor is the same
> > but the interface to the operating system (int 21 or even BIOS) is
> > much simpler than the Win32 interface.
> 
> That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly
> programming is for Linux, and Linux has a DOS-like interrupt-driven
> kernel interface, but it's much more convenient simply because you don't
> need to beat your head against a wall simply to do things like forking.

Learning assembly programming and learning the interface of an OS
are two total different things. You only need a minimal OS interface
for learning assembly programming (read/write files, read keyboard,
write to screen in text/graphics mode). And there is no simpler way
than using the DOS interface (which is also present in the newest
Windows version). After you have learned assembly programing, you
can decide  which OS (Windows/Linux) you would like to use to write
applications in assembler and then learn the API of this OS.

> (Plus, in Linux you can use libc and all of the other C libraries your
> system comes with. Which is damned simpler than reinventing the wheel,
> especially for new programmers, not to mention giving new assembly
> programmers experience in a very valuable area: interfacing with C code,
> either calling it or being called by it.)

Learning assembly programming is to learn to use the instruction set
of the processor to effective solve a given problem. It has 
nothing to with calling libraries or interfacing with HLL (that
belongs to learning the HLL).


> > And you can use almost all
> > 32 bit instructions and addressing modes also in real/V86 mode.
> 
> Then why, pray tell, bother with V86 at all? Why not just go 32-bit all
> the way and forget about things like segments? (OK, 32-bit chips have
> segments. 4 Gibibyte segments. And if you need more RAM than that, why
> the hell are you writing in assembly?)

If you restrict to 64k then you need no real mode segments. "DOS"
com programs are very similar to Win32 programs, but much easier
to understand and concerning assembly programming you will learn
exactly the same. Just look at the posted example, the main code
is identical, but there is nearly no overhead for the com program.

 
> > The only restriction is the limit of 64k memory (without using
> > segmentation) which surely isn't a limitation for learning
> > assembly programming.
> 
> I disagree: It's a rationalization for using a broken system, and it
> will cripple new assembly programmers until they finally move on to
> semi-modern chips. 4 Gibibytes seems tiny now that 64-bit chips are
> coming down from Mount Server, but 4 Gibibytes is more than enough for
> small programs at the moment. 64 Kibibytes /is not/.

We are speaking about LEARNING assembly programming and for that
purpose 64k are enough. It is a different thing if you want to
write real applications in assembler. But in order to write
applications in assembler you first have to learn assembly programing
which is much easier if you use v86 mode. Besides, nobody will write
applications in assembler any more (that is much more obsolete than
a 8086 processor). Use a HLL and if necessary an inline assembler or
link to small piece of code written in assembler.

> > As an example a simple program which reads from stdin and writes
> > to stdout, converting all upper case characters to lower case.
> > To make it compatible with the win32 version, it uses mostly
> > 32 bit instructions. But even then the generated executable
> > file size is only 109 bytes.
> 
> Executable size? Dick-waving nonsense. Blocks on a hard drive are larger
> than that. You gain nothing by stripping the binary to less than one or
> two Kibibytes.

You are right, it doesn't matter how much disc space is needed for
a program. But we are speaking about learning assembly programming.
And it does matter if a beginner has to understand 1000 or only 100
bytes to successfully run his first assembler program.


> I'm aware that this was cross-posted to alt.lang.asm. But why would you
> hype V86 and other Intel things if your code wasn't even going to be for
> Intel chips?

It is x86 code, but I use 32 bit instructions and addressing modes 
since more than 10 years now in real/V86 mode.
0
Reply Herbert 1/25/2004 11:31:57 AM

Herbert Kleebauer wrote:

> August Derleth wrote:
> 
>>Herbert Kleebauer wrote:
> 
> 
>>>But even if an Intel 32 bit processor is used, a beginner always
>>>should start learning assembly programming in real or V86 mode and
>>>not in protected mode.
>>
>>Should all new drivers start out with a Model-T, too? 
> 
> 
> I didn't speak of an ancient 8086 processor. Even the newest x86 processor
> supports the three modes: real/V86/protected mode. And you can use the 
> 32 bit instructions and all the 32 bit addressing modes in any of this
> three modes. So it doesn't matter at all which of this modes you use to
> LEARN assembly programing. But it is important to use an operating 
> system with a simple interface so you can concentrate on the language
> of the processor and don't have to spend much more time with the OS 
> interface than with the processor instructions. And the int21
> interface is much easier to use (and still supported in the newest
> MS operating systems for V86 mode) than the Win32 interface.

But, as I said, the int 21h interface really isn't tied to any mode. You 
can access ah/al and so on even in pure 32-bit mode, and you don't need 
to bother with all of the botches of Intel's 16-bit systems.

And if you are using the 32-bit addressing modes and opcodes in V86 
mode, why not drop the last pretenses of `simplicity' and move into 
32-bit protected mode? It really isn't that difficult, and it can save 
you from shooting yourself in the foot: In protected mode, it becomes 
impossible to scribble on memory you don't own. What could have been an 
OS-corrupting error becomes a much easier to understand segfault error 
on Linux, for example, because Linux has nothing to do with V86. (Linux 
has a syscall to move a specific process into V86 mode, which to my 
knowledge is only used by one program: dosemu, the virtual x86 system 
capable of hosting a DOS-like OS plus BIOS. Other than that, Linux is 
just another Unix.)

> 
> Now to your example, how to learn to drive a car. Nobody says you
> should use a Model-T, use the a modern car (X86). But do you think a
> beginner should start in the rush hour in the streets of New York
> (Windows interface)? Wouldn't it be much better to use a street
> without public traffic ("DOS", which doesn't really mean DOS,
> but the int21 interface for v86 programs in Windows). Then you
> can concentrate on your car and needn't to worry about all
> the other things happening on the streets of NY. Maybe this
> empty street is only a few miles (64 kbyte) instead of the 
> hundreds of miles of streets in NY (4 Gbyte), but that is enough
> to learn all about your car. And once you are familiar with your
> car you can start to drive through NY.

And I think protected mode is simpler, and libc more convenient, than 
anything DOS has to offer. I can `hop in my car' (forget about 
segmenting) and use convenient `routes' (the libc syscalls), replete 
with `road maps' (the man pages for those syscalls, which document 
syntax, semantics, and expected return values) and the ability to `make 
my own roads' (write something in C if it isn't obvious how to do it in 
assembly). And writing it in C is a good method of learning how it can 
be done, since most C compilers (gcc being one of them) will output 
assembly instead of just binaries.

V86 mode isn't a comfy dirt road. It's having to grind the crank on your 
engine and distill your own gas from petroleum. And 32-bit protected 
mode isn't a complex NYC. It's being able to ignore the engine most of 
the time and knowing there's well-paved roads to wherever you most want 
to go.

>  
> 
>>No, I simply cannot agree with this statement. It's wrong, and will lead
>>to scaring off more people from assembly than is really needed. Intel
>>botched the 16-bit generation completely, and nothing can convince me
>>that it's better to start with that generation of chips (or an emulation
>>thereof).
> 
> 
> Sorry, but I don't understand how a easy to use OS interface
> can scare off people. If you look at a piece of code without
> an OS call, you can't decide if this is code for V86 or
> protected mode. V86 is not only the emulation of an 8086, it
> supports the same 32 bit addressing modes as protected mode.

Here I was wrong: I was still thinking of V86 mode only allowing 
8086-style addressing modes and such like. But my later contention 
stands: If you're using 32-bit addressing and opcodes, why not use 
protected-mode all the way?

> 
> 
> 
>>>The language of the processor is the same
>>>but the interface to the operating system (int 21 or even BIOS) is
>>>much simpler than the Win32 interface.
>>
>>That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly
>>programming is for Linux, and Linux has a DOS-like interrupt-driven
>>kernel interface, but it's much more convenient simply because you don't
>>need to beat your head against a wall simply to do things like forking.
> 
> 
> Learning assembly programming and learning the interface of an OS
> are two total different things. You only need a minimal OS interface
> for learning assembly programming (read/write files, read keyboard,
> write to screen in text/graphics mode). And there is no simpler way
> than using the DOS interface (which is also present in the newest
> Windows version). After you have learned assembly programing, you
> can decide  which OS (Windows/Linux) you would like to use to write
> applications in assembler and then learn the API of this OS.

Actually, I disagree with you here. (As I'm sure you know.) The DOS API 
is rather more complex than the libc interface on Linux simply because 
libc is more consistent: Whereas DOS makes you memorize how each 
register is used by each interrupt, libc simply does everything on the 
stack. You push your arguments, make the call, and pop the result. It is 
/not/ efficient, and Linux /does/ define a kernel interface which is 
very DOS-like, but I think simplicity and consistency are more important 
than speed.

(I suspect libc on Win32 is much like that on Linux. It would surprise 
me if it were different in important respects.)

> 
> 
>>(Plus, in Linux you can use libc and all of the other C libraries your
>>system comes with. Which is damned simpler than reinventing the wheel,
>>especially for new programmers, not to mention giving new assembly
>>programmers experience in a very valuable area: interfacing with C code,
>>either calling it or being called by it.)
> 
> 
> Learning assembly programming is to learn to use the instruction set
> of the processor to effective solve a given problem. It has 
> nothing to with calling libraries or interfacing with HLL (that
> belongs to learning the HLL).

/Au contraire/: Assembly isn't a stand-alone language anymore in most 
cases. Interfacing with an HLL (and I don't know how HL C is ;) ) is not 
only an exercise in simplicity (via libc), it's practice in how to 
structure your own subroutines (learn which registers you must save, 
learn how to create and destroy a stack frame, learn how to access 
arguments, and learn how to properly return a value) and create your own 
libraries.

Learning the instruction set isn't hard. Learning memory is more 
difficult, but 32-bit protected mode makes it easier in addition to 
giving you a nice net. Learning how to structure a program logically and 
how to write consistent code that makes use of the environment is more 
difficult, and it isn't something DOS is especially good at teaching.

> 
> 
> 
>>>And you can use almost all
>>>32 bit instructions and addressing modes also in real/V86 mode.
>>
>>Then why, pray tell, bother with V86 at all? Why not just go 32-bit all
>>the way and forget about things like segments? (OK, 32-bit chips have
>>segments. 4 Gibibyte segments. And if you need more RAM than that, why
>>the hell are you writing in assembly?)
> 
> 
> If you restrict to 64k then you need no real mode segments. "DOS"
> com programs are very similar to Win32 programs, but much easier
> to understand and concerning assembly programming you will learn
> exactly the same. Just look at the posted example, the main code
> is identical, but there is nearly no overhead for the com program.

I looked at both examples, and I think the second was rather 
over-complex. /None/ of my assembly programs are that complex, given so 
simple a task. And if they do become that complex, I write in a 
different language. ;)

> 
>  
> 
>>>The only restriction is the limit of 64k memory (without using
>>>segmentation) which surely isn't a limitation for learning
>>>assembly programming.
>>
>>I disagree: It's a rationalization for using a broken system, and it
>>will cripple new assembly programmers until they finally move on to
>>semi-modern chips. 4 Gibibytes seems tiny now that 64-bit chips are
>>coming down from Mount Server, but 4 Gibibytes is more than enough for
>>small programs at the moment. 64 Kibibytes /is not/.
> 
> 
> We are speaking about LEARNING assembly programming and for that
> purpose 64k are enough. It is a different thing if you want to
> write real applications in assembler. But in order to write
> applications in assembler you first have to learn assembly programing
> which is much easier if you use v86 mode. Besides, nobody will write
> applications in assembler any more (that is much more obsolete than
> a 8086 processor). Use a HLL and if necessary an inline assembler or
> link to small piece of code written in assembler.

Why give a learner a crippled tool when he already owns a fully-featured 
one? I say, 32-bit protected mode leaves behind a lot of baggage and 
opens new doors of convenience.

Learning on an emulation of an antique is not simpler in this case, it 
is simply different, and it brings its own baggage with it. libc may 
have baggage from your point of view, but it's the kind of baggage 
assembly programmers deal with now and will have to deal with for as 
long as humans code in assembly. Besides, learning about the stack is a 
nice brain-expander that should help them learn to visualize other data 
structures, such as linked lists and hashes.

> 
> 
>>>As an example a simple program which reads from stdin and writes
>>>to stdout, converting all upper case characters to lower case.
>>>To make it compatible with the win32 version, it uses mostly
>>>32 bit instructions. But even then the generated executable
>>>file size is only 109 bytes.
>>
>>Executable size? Dick-waving nonsense. Blocks on a hard drive are larger
>>than that. You gain nothing by stripping the binary to less than one or
>>two Kibibytes.
> 
> 
> You are right, it doesn't matter how much disc space is needed for
> a program. But we are speaking about learning assembly programming.
> And it does matter if a beginner has to understand 1000 or only 100
> bytes to successfully run his first assembler program.

I say byte count is less of an issue than consistency. Reduce the number 
of concepts they need to master, and they'll be able to create larger 
programs sooner. libc is great at managing complexity.

> 
> 
> 
>>I'm aware that this was cross-posted to alt.lang.asm. But why would you
>>hype V86 and other Intel things if your code wasn't even going to be for
>>Intel chips?
> 
> 
> It is x86 code, but I use 32 bit instructions and addressing modes 
> since more than 10 years now in real/V86 mode.

Well, I was wrong here. You did write in a variant of assembly that 
could be translated to x86 opcodes, but nothing I'd call 32-bit or even 
AT&T syntax. You apparently took PDP syntax and pared it down to work on 
the much-simplified x86 instruction set. I've never seen that done 
before, and I'd be interested to know which assembler accepts your 
source code.

In other words, it's probably logical enough to you and whatever 
assembler you use. But it's different enough from every other piece of 
x86 code it's nigh-unreadable to 95% of the people here.

-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/25/2004 7:51:37 PM

Matt Taylor wrote:

>  "August Derleth" <see@sig.now> wrote in message
> news:XWEQb.6301$dF4.1203@fe02.usenetserver.com...
> <snip>
> 
>>>The language of the processor is the same
>>>but the interface to the operating system (int 21 or even BIOS) is
>>>much simpler than the Win32 interface.
>>
>>That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly
>>programming is for Linux, and Linux has a DOS-like interrupt-driven
>>kernel interface, but it's much more convenient simply because you don't
>>need to beat your head against a wall simply to do things like forking.
> 
> 
> What is true for Linux is also true for Win32. System calls are done via
> interrupts and are quite convenient. Most Win32 functions aren't horribly
> daunting, and it is also possible to call the C runtime functions which are
> probably more familiar to some.

I suspected as much, but I've never done Win32 programming at the 
assembly level.

> 
> <snip>
> 
>>>        @=$100
>>>loop:   bsr.l   getc            ; get char from stdin
>>>        cmp.l   #-1,r0          ; EOF
>>>        bne.b   _10             ; branch if not
>>>        moveq.l #0,-(sp)
>>>        bsr.l   ExitProcess     ; exit program
>>>_10:    cmp.b   #'A',r0
>>>        blo.b   _20
>>>        cmp.b   #'Z',r0
>>>        bhi.b   _20
>>>        add.b   #'a'-'A',r0
>>>_20:    bsr.l   putc            ; write char to stdout
>>>        br.b    loop            ; go on
>>>
>>>
>>>putc:   movem.l r0-r7,-(sp)
>>>        move.b  r0,_buf
>>>        move.b  #$40,m0
>>>        move.w  #_buf,r1
>>>        move.w  #1,r2
>>>        move.w  #1,r3
>>>        trap    #$21
>>>        movem.l (sp)+,r0-r7
>>>        rts.l
>>>_buf:   dc.b    0
>>>
>>>
>>>getc:   movem.l r0-r7,-(sp)
>>>        move.b  #$3f,m0
>>>        move.w  #_buf,r1
>>>        move.w  #1,r2
>>>        eor.w   r3,r3
>>>        trap    #$21
>>>        bcs.b   _10
>>>        cmp.w   r0,r2
>>>        bne.b   _10
>>>        movem.l (sp)+,r0-r7
>>>        move.b  _buf,r0
>>>        rts.l
>>>_10:    movem.l (sp)+,r0-r7
>>>        move.l  #-1,r0
>>>        rts.l
>>>_buf:   dc.b    0
>>>
>>>
>>>ExitProcess:
>>>        move.b  #$4c,m0
>>>        trap    #$21
>>
>>I notice you /aren't even using 8088 opcodes/. Post-increment indexing
>>modes? I guess it's the 68000, if it's a microprocessor, but it could
>>(possibly) be a PDP or a VAX.
> 
> 
> More likely someone took PDP/VAX as a starting point and grafted x86 onto
> it. The pre-decrement and post-increment indexing correspond to push/pop
> instructions. The trap mneumonic replaces the int mneumonic. Other analogues
> are apparent as well (such as DOS functions being called).

I was tired at the time, but you must admit it's very odd-looking. My 
pattern-detecting brain was thrown for a loop at this point, and it 
wasn't until I looked at it now that I finally grasped the similarities. 
I'm still not sure which registers his r0-r7 match up with, though (is 
r0 eax? is r0 ebx? how does he access ah? etc.). And, of course, I have 
no idea which assembler his code is meant for. I think it would be 
interesting to know. (What can I say? The predictibility has become 
boring. I want to learn a gratuitously different syntax for the same old 
ISA. ;) )

> 
> -Matt
> 
> 


-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/25/2004 7:51:39 PM

On Sun, 25 Jan 2004 02:17:44 +0000 (UTC), in
<XWEQb.6301$dF4.1203@fe02.usenetserver.com>, August Derleth
<see@sig.now> wrote:

>Herbert Kleebauer wrote:
>
>> But even if an Intel 32 bit processor is used, a beginner always 
>> should start learning assembly programming in real or V86 mode and
>> not in protected mode.
>
>Should all new drivers start out with a Model-T, too? Or all new pilots 
>start off with a biplane?

The modern alternative to the Model-T is acceptable for a
beginner, but let's not start off in downtown rush hour traffic.
As for the biplane, given a choice for new pilots of a biplane or
a 747, do I take it correctly that you would recommend the 747?

>> The language of the processor is the same
>> but the interface to the operating system (int 21 or even BIOS) is
>> much simpler than the Win32 interface.
>
>That's a failing of Win32, not 32-bit chips. All of my 32-bit assembly 
>programming is for Linux, and Linux has a DOS-like interrupt-driven 
>kernel interface, but it's much more convenient simply because you don't 
>need to beat your head against a wall simply to do things like forking.

A failing of Win32 or not, it is a problem when a beginner has to
spend more time learning the interface than learning to use
assembly language.

>In short, wanting to use a specific OS and/or API style (even one as 
>ancient as DOS) is no reason to stick with 16-bit Intel chips.

Did anyone insist on strictly 16-bit hardware?  If so I missed
it.

>> And you can use almost all 
>> 32 bit instructions and addressing modes also in real/V86 mode.
>
>Then why, pray tell, bother with V86 at all? Why not just go 32-bit all 
>the way and forget about things like segments? (OK, 32-bit chips have 
>segments. 4 Gibibyte segments.  And if you need more RAM than that, why 
>the hell are you writing in assembly?)

Since when did the availability of seemingly endless RAM impose a
restriction on using assembly language?  You aren't making any
sort of rational case for starting a beginning assembly language
programmer off with Win32 or protected mode programming; you're
just trotting out your own personal preferences.

>> The only restriction is the limit of 64k memory (without using
>> segmentation) which surely isn't a limitation for learning
>> assembly programming.
>
>I disagree: It's a rationalization for using a broken system, and it 
>will cripple new assembly programmers until they finally move on to 
>semi-modern chips.

Probably so, but you don't start new pilots off in a 747.

>4 Gibibytes seems tiny now that 64-bit chips are 
>coming down from Mount Server, but 4 Gibibytes is more than enough for 
>small programs at the moment. 64 Kibibytes /is not/.

For a beginning assembly language programmer 64K isn't enough?
Are you serious?

>> As an example a simple program which reads from stdin and writes
>> to stdout, converting all upper case characters to lower case.
>> To make it compatible with the win32 version, it uses mostly
>> 32 bit instructions. But even then the generated executable
>> file size is only 109 bytes.
>
>Executable size? Dick-waving nonsense. Blocks on a hard drive are larger 
>than that. You gain nothing by stripping the binary to less than one or 
>two Kibibytes.

It isn't a case of stripping the binary.  It's a case of writing
the program in assembly language targeting a real mode x86
processor and finding that the compiled machine code totals only
a few hundred bytes.  What would you have the programmer do -
insert 10X as many nops as other instructions to bloat it up to
2K?  Nobody was arguing smaller is better.  The point I got was
that small is the *nature* of beginning assembly language
programs so the availability of a huge address space, and the
actual RAM to fill it is immaterial to the discussion.  Nor is it
necessary to wade thru the complexity of learning the interface
to Win32 to write a beginner's assignment involving a bit of file
I/O.

It isn't that real mode is globally better; it's just better in
this limited situation.  If the beginner likes assembly language
programming, move him up to the more complex OS platform.  But
start him off on the more complex platform and risk losing him as
an assembly language programmer for life.

-- 
Jim Higgins, quasimodo AT yahoo DOT com
icbm: 33.55.34N, 80.24.21W

0
Reply Jim 1/25/2004 9:52:28 PM

On Sat, 24 Jan 2004 17:59:38 +0000 (UTC), Mr Dygi
<dygimailNo@SPAMpoczta.fm> wrote:

>Could you tell me in few words what a different in using real/protected 
>mode or V86 (?). What V86 is?
In order to understand the various modes, you must understand the
history of CPU's.  

Intel started long ago with the 4040, which was used only in
calculators.  Later, the 8080 was designed and used in CP/M based
systems, then came along the 8088 (and soon after 8086), which was
used on PC's, XT's, and clones.  These systems used 16-bit
instructions on what was an 8-bit CPU (or in the case of the 8086 a
16-bit cpu with an 8-bit bus), and in order to access more memory than
possible with a single 16-bit register, Intel used segment:offset
scheme of doing things.  The segment was shifted 4 bits and added to
the offset to point to the actual memory location.  This meant that
any given memory location could be referenced in several different
ways, eg.


000:400h  
 is  the same as
40h:0h

And many other potential combinations.  You had 4 segment registers on
the 8088/8086, CS,DS,ES, and SS.  SS was used for the stack, CS for
code, DS for data and ES was an extra register often used with data
for copying to/from one location to another.  The 8088 could access a
whole whopping 1meg of memory this way.  Along came the 80286 and with
it the ability to access 16 megs, but to do so the 80286 had to forget
about the 8088's way of doing things.  So to access 16megs of memory,
the 80286 created Selectors that pointed to memory.  A selector has a
starting point and a size, and access rights to determine if the CPU
can read, write, or execute the memory. Since we used selectors that
was created in memory and the segment registers just pointed to which
selector we wanted to use, we could now use more than 16 bits to store
the memory location.  This allowed the 80286 to access all 16 megs of
memory it could handle.  This was good, but along came the 80386,
which made a lot of things WAY easier for programmers.  Better
instructions, access to 4 Gigabytes of memory, better memory
handling/virtual memory access, etc.  Along with access to more memory
a Virtual'86 mode was also created if I'm not mistaken...  This was an
interesting mode.... With it, the CPU could be in protected mode, but
somehow DOS programs could run in real mode, while protected mode apps
run in protected mode, but the DOS apps are still under some protected
mode rules....  You can't go messing around with every single CPU
instruction in Virtual 86 mode... Alot of the CPU detection
instructions won't work in Virtual'86 mode... O.k. I left a lot out,
but it hopefully gives you a brief idea of what is meant by
real/protected/v86 mode....

0
Reply John 1/26/2004 12:05:00 AM

On Sun, 25 Jan 2004 12:31:57 +0100, Herbert Kleebauer <klee@unibwm.de>
wrote:

>> Should all new drivers start out with a Model-T, too? 
>
>I didn't speak of an ancient 8086 processor. Even the newest x86 processor
>supports the three modes: real/V86/protected mode. And you can use the 
>32 bit instructions and all the 32 bit addressing modes in any of this
What about the fact that CPU its self BOOTS up in REAL mode.... I mean
Gee, if you have the illusion that your going to start off programming
your own OS (as every beginner at ASM seems to have) completly in
assembly language, then it'd seem you'd WANT to learn real mode
first.... Since after all, you'll need to know enough about it to get
your butt in protected mode....

0
Reply John 1/26/2004 12:05:02 AM

On Mon, 26 Jan 2004 00:05:02 +0000 (UTC)
"John H. Guillory" <jj206@remoooooovethisdrizzle.com> wrote:

:What about the fact that CPU its self BOOTS up in REAL mode.... I mean
:Gee, if you have the illusion that your going to start off programming
:your own OS (as every beginner at ASM seems to have) completly in
:assembly language, then it'd seem you'd WANT to learn real mode
:first.... Since after all, you'll need to know enough about it to get
:your butt in protected mode....

It's been a long time since I wrote code to switch from real to protected
mode, and my memory of it grows dim, but I'm fairly certain that I didn't
need any int 21h calls to do so. :-)

0
Reply Charles 1/26/2004 12:15:20 AM

"Herbert Kleebauer" <klee@unibwm.de> wrote in message
news:4013A92D.8F6A1FF1@unibwm.de...
> August Derleth wrote:
> > Herbert Kleebauer wrote:
>
> > > But even if an Intel 32 bit processor is used, a beginner always
> > > should start learning assembly programming in real or V86 mode and
> > > not in protected mode.
> >
> > Should all new drivers start out with a Model-T, too?
>
> I didn't speak of an ancient 8086 processor. Even the newest x86 processor
> supports the three modes: real/V86/protected mode. And you can use the
> 32 bit instructions and all the 32 bit addressing modes in any of this
> three modes. So it doesn't matter at all which of this modes you use to
> LEARN assembly programing. But it is important to use an operating
> system with a simple interface so you can concentrate on the language
> of the processor and don't have to spend much more time with the OS
> interface than with the processor instructions. And the int21
> interface is much easier to use (and still supported in the newest
> MS operating systems for V86 mode) than the Win32 interface.
<snip>

No, this is simply not true. Whether I put the data in registers or push it
to the stack, there is no difference in complexity. Calling functions with
actual names rather than some coded numbers is much easier to remember, so
if I were to make a case for either calling convention I would say that
Linux/Win32 is easier than DOS.

Here are 2 pieces of code, one for DOS and the other for Win32:

; DOS code
mov ah, 1
int 0x21 ; read a character from stdin with echo

mov ax, 0x4C00
int 0x21 ; exit to DOS

; Win32 code
call getch

push 0
call exit

So what exactly are your metrics for easiness? Shorter code? Here the Win32
code is shorter by 1 instruction. The gets() and puts() functions are only
slightly trickier since one must pass a pointer to __iob.

<snip>
> We are speaking about LEARNING assembly programming and for that
> purpose 64k are enough. It is a different thing if you want to
> write real applications in assembler. But in order to write
> applications in assembler you first have to learn assembly programing
> which is much easier if you use v86 mode. Besides, nobody will write
> applications in assembler any more (that is much more obsolete than
> a 8086 processor). Use a HLL and if necessary an inline assembler or
> link to small piece of code written in assembler.

So why bother with learning 16-bit at all if you're not going to use it?
Teach the novice to do inline assembly and tackle real problems. I cannot
count the number of times someone has asked (either here or elsewhere) why
they can't use interrupts to make DOS calls from Windows. Then there are
endless questions about segmentation. You've pointed out that 32-bit
addressing can be used in v8086 or real-mode, but none of the tutorials
mention this! The novice is always directed to use convoluted 16-bit
addressing modes. Even with 32-bit addressing modes there are still caveats
for the 16-bit programmer.

The main Win32 question I hear is, "Why does my program crash?" where the
crash stems from incorrect calling conventions or from calling a DLL
function directly. These questions are much more easily answered. Also, they
are completely avoided by using the C runtime functions and statically
linking to them.

> > > As an example a simple program which reads from stdin and writes
> > > to stdout, converting all upper case characters to lower case.
> > > To make it compatible with the win32 version, it uses mostly
> > > 32 bit instructions. But even then the generated executable
> > > file size is only 109 bytes.
> >
> > Executable size? Dick-waving nonsense. Blocks on a hard drive are larger
> > than that. You gain nothing by stripping the binary to less than one or
> > two Kibibytes.
>
> You are right, it doesn't matter how much disc space is needed for
> a program. But we are speaking about learning assembly programming.
> And it does matter if a beginner has to understand 1000 or only 100
> bytes to successfully run his first assembler program.
<snip>

Number of instructions is more important, and as I've been saying, most C
runtime functions have nearly a 1:1 correspondance with DOS system
functions. It is also easier for a person to remember names than it is to
remember numbers. Beside that, a lot of assembly programmers come from C/C++
experience. It is far simpler for the novice who has already learned his
native tools to continue using them.

-Matt


0
Reply Matt 1/26/2004 3:17:05 AM

"Matt Taylor" <para@tampabay.rr.com> wrote in message
news:Vu%Qb.111831$873.1906321@twister.tampabay.rr.com...
<snip>
> So what exactly are your metrics for easiness? Shorter code? Here the
Win32
> code is shorter by 1 instruction. The gets() and puts() functions are only
> slightly trickier since one must pass a pointer to __iob.
<snip>

Now I get to correct myself. I was thinking of fgets() and fputs(). The
gets() and puts() functions assume stdin, so they are just as simple as DOS
system calls on both Win32 and Linux.

-Matt


0
Reply Matt 1/26/2004 3:38:28 AM

August Derleth <see@sig.now> wrote:

>Herbert Kleebauer wrote:
>> 
>> There are still much more 4/8 bit processors sold than 16/32/64 processors.
>
>I'd like a citation for this claim. Are seriously tiny embedded systems 
>truly that common?

Does it really seem that surprising?  Virtually every appliance with a
power supply has a microprocessor in it, and only a small fraction of them
need anything more powerful than a PIC or 8051.  Rest assured that NO
equipment maker is going to pay for a single bit of processor more than
they need.  The ABS on your car probably uses an 8-bit processor.  Your
microwave almost certainly does.  Your telephone does.  Your refrigerator
and washing machine probably do.

Those applications completely dwarf applications for 32-bit processors.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 1/26/2004 4:58:36 AM

I'm in the mood for a little nitpicking.

> Intel started long ago with the 4040, which was used only in

They started with the world's first microprocessor, the 4004, in 1971. 
Development had started in 1969. It was a 4 bit chip. In 1972 Intel 
introduced the 8 bit 8008.

> calculators.  Later, the 8080 was designed and used in CP/M based

Correct. This was in 1974. The 8080 was an 8 bit processor with 16 bit 
addresses, and it was the model for the incredibly popular Z80.

> systems, then came along the 8088 (and soon after 8086), which was
> used on PC's, XT's, and clones.  These systems used 16-bit
> instructions on what was an 8-bit CPU (or in the case of the 8086 a
> 16-bit cpu with an 8-bit bus), and in order to access more memory than

Very common mistake. The 8086 was released in 1978, and it is a true 16 
bit processor. To allow for cheaper circuit boards, Intel released the 
8088 in 1979. This is an exact copy of the 8086, but with an 8 bit 
external data bus. It is a 16 bit processor inside, just like the 8086.

> possible with a single 16-bit register, Intel used segment:offset
> scheme of doing things.  The segment was shifted 4 bits and added to
> the offset to point to the actual memory location.  This meant that
> any given memory location could be referenced in several different
> ways, eg.

Now this is all true. Then came the 80286 with 16 bit protected mode, 
then the 80386 with 32 bit protected mode, and the rest have essentially 
been fast 386s.


-- 
Remove the furry animal from my address to send email:

   bjarni.ferret@update.ferret.uu.se

0
Reply Bjarni 1/26/2004 5:26:41 AM

Tim Roberts wrote:

> August Derleth <see@sig.now> wrote:
> 
> 
>>Herbert Kleebauer wrote:
>>
>>>There are still much more 4/8 bit processors sold than 16/32/64 processors.
>>
>>I'd like a citation for this claim. Are seriously tiny embedded systems 
>>truly that common?
> 
> 
> Does it really seem that surprising?  Virtually every appliance with a
> power supply has a microprocessor in it, and only a small fraction of them
> need anything more powerful than a PIC or 8051.  Rest assured that NO
> equipment maker is going to pay for a single bit of processor more than
> they need.  The ABS on your car probably uses an 8-bit processor.  Your
> microwave almost certainly does.  Your telephone does.  Your refrigerator
> and washing machine probably do.

I simply didn't realize those little things would have general-purpose 
programmable logic in them, as opposed to special-purpose circuitry and 
various amounts of ROM. I know the era of the electromechanical system 
is over, but has everyone moved from the simple special-purpose chips to 
the more complex 8051s and such?

-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/26/2004 6:37:14 AM

"Bjarni Juliusson" <bjarni.ferret@update.ferret.uu.se> wrote in message
news:N21Rb.79971$dP1.202378@newsc.telia.net...
> I'm in the mood for a little nitpicking.
>
> > Intel started long ago with the 4040, which was used only in
>
> They started with the world's first microprocessor, the 4004, in 1971.
> Development had started in 1969. It was a 4 bit chip. In 1972 Intel
> introduced the 8 bit 8008.
>
> > calculators.  Later, the 8080 was designed and used in CP/M based
>
> Correct. This was in 1974. The 8080 was an 8 bit processor with 16 bit
> addresses, and it was the model for the incredibly popular Z80.
>
> > systems, then came along the 8088 (and soon after 8086), which was
> > used on PC's, XT's, and clones.  These systems used 16-bit
> > instructions on what was an 8-bit CPU (or in the case of the 8086 a
> > 16-bit cpu with an 8-bit bus), and in order to access more memory than
>
> Very common mistake. The 8086 was released in 1978, and it is a true 16
> bit processor. To allow for cheaper circuit boards, Intel released the
> 8088 in 1979. This is an exact copy of the 8086, but with an 8 bit
> external data bus. It is a 16 bit processor inside, just like the 8086.
>
> > possible with a single 16-bit register, Intel used segment:offset
> > scheme of doing things.  The segment was shifted 4 bits and added to
> > the offset to point to the actual memory location.  This meant that
> > any given memory location could be referenced in several different
> > ways, eg.
>
> Now this is all true. Then came the 80286 with 16 bit protected mode,
> then the 80386 with 32 bit protected mode, and the rest have essentially
> been fast 386s.
>

hehe... yah... my A+ instructor told us just the other day that a 586 is
simply two 486's put together in one package.... (what i think he was
actually trying to explain at the time, was the fact that the 586 had two
instruction pipelines.... but he didn't do a very good job.... looking
around the room, he left the other students more confused than before)...


0
Reply Bx 1/26/2004 6:37:35 AM

Matt Taylor wrote:
> "Herbert Kleebauer" <klee@unibwm.de> wrote in message

 
> No, this is simply not true. Whether I put the data in registers or push it
> to the stack, there is no difference in complexity. Calling functions with
> actual names rather than some coded numbers is much easier to remember, so
> if I were to make a case for either calling convention I would say that
> Linux/Win32 is easier than DOS.
> 
> Here are 2 pieces of code, one for DOS and the other for Win32:
> 
> ; DOS code
> mov ah, 1
> int 0x21 ; read a character from stdin with echo
> 
> mov ax, 0x4C00
> int 0x21 ; exit to DOS

This are four processor instructions and the generated executable
contains 9 bytes: B4 01 CD 21 B8 00 4C CD 21
This is easy to understand for any beginner.

 
> ; Win32 code
> call getch
> 
> push 0
> call exit

And that is a joke? That's why beginner learning assembly
programming in win32 think, INVOKE is a processor instruction
and exit is some function stored in the CPU, because you can
call it without providing it.

Now let's look what an assembly programmer has to learn
to end a program by calling ExitProcess.


6a 00                       moveq.l #0,-(sp)
ff 15 00401008              jsr.l   (ExitProcess)

You only need 2 instructions. The first is a simple push (no
problem to understand), but the second is an indirect call to
a subroutine. In order to execute this call you have to provide
a memory location where this address is stored:

ExitProcess:   dc.l	AddressOfExitSubroutine

But where to get this "AddressOfExitSubroutine"? You have to
ask the loader to insert this address at the location
"ExitProcess" at load time. In order to do this, you have to
specify at a predefined location in the exe file a pointer to
and the length of two tables:

dc.l    imp_start,imp_size      ; Import Directory
dc.l    iat_start,iat_size      ; Import Address Table

In the Import Address Table are all the memory locations
where the subroutine addresses are stored:

       iat_start=@-ImageBase
KERNEL32_thunk:
ExitProcess::   dc.l        KERNEL32_ExitProcess        -ImageBase
                dc.l        0
       iat_size=@-ImageBase-iat_start


In the Import Directory you have to make an entry for
any DLL imported:

imp_start==@-ImageBase
imp:

dc.l    KERNEL32_import     -ImageBase
dc.l    0
dc.l    0
dc.l    KERNEL32_name       -ImageBase
dc.l    KERNEL32_thunk      -ImageBase

dc.l    0
dc.l    0
dc.l    0
dc.l    0
dc.l    0

imp_size==@-imp


Beside the pointer to the Import Address Table there a three other
pointers to data which you have also to supply:

KERNEL32_name:
            dc.b    'KERNEL32.dll',0
            even

KERNEL32_import:
            dc.l    KERNEL32_ExitProcess        -ImageBase
            dc.l    0
            even

KERNEL32_ExitProcess:
            dc.w    0
            dc.b    'ExitProcess',0
            even


All this data structures a beginner has to supply and to understand
before he can exit his program. Now compare this with with the 5 bytes
in the "DOS" version. And don't tell me, an assembly programmer doesn't
have to know this. Otherwise it is just a HLL with an inline assembler
where you write a part of the program using processor instructions
and the rest is generated by the compiler/"High Level Assembler". 
 
> So what exactly are your metrics for easiness? Shorter code? Here the Win32
> code is shorter by 1 instruction. The gets() and puts() functions are only
> slightly trickier since one must pass a pointer to __iob.

Now just recount.


> You've pointed out that 32-bit
> addressing can be used in v8086 or real-mode, but none of the tutorials
> mention this! 

Sorry, but there is only one documentation for learning assembly 
programming and that is the processor manual and there you will
find all information about the available addressing modes. 

 
> The main Win32 question I hear is, "Why does my program crash?" where the
> crash stems from incorrect calling conventions or from calling a DLL
> function directly. These questions are much more easily answered. Also, they
> are completely avoided by using the C runtime functions and statically
> linking to them.

That is not assembly programming, that is the generation of a 
sequence of operating system / library calls. Look at the simple
task to draw a circle on the screen. In "DOS" mode you make an
int10 to switch to graphics mode and then you can concentrate
on writing the circle function in assembler. The output
to screen is a simple move instruction. Now compare this with
the overhead in Windows to set a single pixel on the screen.
But if you have managed this, you don't need to worry about the
assembler code for the circle, simple call some draw_circle
function in a graphics library. That has nothing to do with
assembly programming.

0
Reply Herbert 1/26/2004 11:26:01 AM

"August Derleth" <see@sig.now> wrote in message
news:IF1Rb.10471$dF4.2130@fe02.usenetserver.com...
> Tim Roberts wrote:
>
>
> I simply didn't realize those little things would have general-purpose
> programmable logic in them, as opposed to special-purpose circuitry and
> various amounts of ROM. I know the era of the electromechanical system
> is over, but has everyone moved from the simple special-purpose chips to
> the more complex 8051s and such?
>
Yes. It's much cheaper to use one of these devices in most cases.
Not the mention the fact that it has probably been at least a decade
since any school has really taught students how to design anything
without using microprocessors :-)
Cheers,
Randy Hyde


0
Reply Randall 1/26/2004 1:13:48 PM

"Herbert Kleebauer" <klee@unibwm.de> wrote in message
news:4014F949.629CF99A@unibwm.de...
> Matt Taylor wrote:
> > "Herbert Kleebauer" <klee@unibwm.de> wrote in message
>
>
> > No, this is simply not true. Whether I put the data in registers or push
it
> > to the stack, there is no difference in complexity. Calling functions
with
> > actual names rather than some coded numbers is much easier to remember,
so
> > if I were to make a case for either calling convention I would say that
> > Linux/Win32 is easier than DOS.
> >
> > Here are 2 pieces of code, one for DOS and the other for Win32:
> >
> > ; DOS code
> > mov ah, 1
> > int 0x21 ; read a character from stdin with echo
> >
> > mov ax, 0x4C00
> > int 0x21 ; exit to DOS
>
> This are four processor instructions and the generated executable
> contains 9 bytes: B4 01 CD 21 B8 00 4C CD 21
> This is easy to understand for any beginner.

As has been pointed out several times already, the length of instructions is
completely and totally irrelevant. We are talking about learning assembly,
right?

> > ; Win32 code
> > call getch
> >
> > push 0
> > call exit
>
> And that is a joke? That's why beginner learning assembly
> programming in win32 think, INVOKE is a processor instruction
> and exit is some function stored in the CPU, because you can
> call it without providing it.

I've never heard of anyone thinking this. If someone does not understand the
concept of libraries, they have a lot more to learn than just assembly
language. Personally, I understood what a library was before I even knew
what assembly language was.

Yes, it is possible to use invoke which makes life even simpler for the
Win32 programmer. I prefer not to use it, but that is another discussion
entirely. For this discussion, my example did not include invoke.

> Now let's look what an assembly programmer has to learn
> to end a program by calling ExitProcess.
>
>
> 6a 00                       moveq.l #0,-(sp)
> ff 15 00401008              jsr.l   (ExitProcess)
>
> You only need 2 instructions. The first is a simple push (no
> problem to understand), but the second is an indirect call to
> a subroutine. In order to execute this call you have to provide
> a memory location where this address is stored:
>
> ExitProcess:   dc.l AddressOfExitSubroutine
<snip>

Since when? That is automatically provided to you unless you hexedit your
own executable. I thought we were talking about learning assembly language,
not writing demos. Besides the fact that one can call exit() instead, it is
still simpler to explain the difference between an indirect/direct call than
it is to explain segmentation. As I said before, most people I've met who
pick up assembly do so *after* learning C. Since C has an analogue for this,
it is quite easy to explain.

> All this data structures a beginner has to supply and to understand
> before he can exit his program. Now compare this with with the 5 bytes
> in the "DOS" version. And don't tell me, an assembly programmer doesn't
> have to know this. Otherwise it is just a HLL with an inline assembler
> where you write a part of the program using processor instructions
> and the rest is generated by the compiler/"High Level Assembler".
<snip>

Utter nonsense. I've never constructed a PE header by hand, and I don't
intend to do that ever. It's a great exercise in futility. All of the tools
I've worked with will build the IAT and related structures automatically.
Nasm will allow me to build my own, but that's a complete waste of time.

Here's the equivalent of B8 00 4C CD 21 using ExitProcess:

bits 32

section .text
extern _ExitProcess@4

_main:
 push 0
 call [_ExitProcess@4]

> > You've pointed out that 32-bit
> > addressing can be used in v8086 or real-mode, but none of the tutorials
> > mention this!
>
> Sorry, but there is only one documentation for learning assembly
> programming and that is the processor manual and there you will
> find all information about the available addressing modes.

Also nonsense. There are a number of tutorials on assembly which take
information from Intel manuals and organize it for the novice. AoA comes
foremost to mind. Personally, I read the 8086 & 80386 manuals, and I thought
they were well-written. Unfortunately newer manuals have too much
information as x86 has exponentially increased in complexity. Most of that
information is for people writing operating systems and is completely
meaningless to the novice.

> > The main Win32 question I hear is, "Why does my program crash?" where
the
> > crash stems from incorrect calling conventions or from calling a DLL
> > function directly. These questions are much more easily answered. Also,
they
> > are completely avoided by using the C runtime functions and statically
> > linking to them.
>
> That is not assembly programming, that is the generation of a
> sequence of operating system / library calls. Look at the simple
> task to draw a circle on the screen. In "DOS" mode you make an
> int10 to switch to graphics mode and then you can concentrate
> on writing the circle function in assembler. The output
> to screen is a simple move instruction. Now compare this with
> the overhead in Windows to set a single pixel on the screen.
<snip>

Yes, and in 320x200 unless you care to explain segmentation, banked modes,
color planes, and other concepts to the novice. At least use DPMI with VESA
2. DirectDraw isn't ideal, but at least one can create a framework and then
forget about it.

Besides, what does that have to do with learning assembly? Surely you don't
think that the demoscene is the *only* reason people learn assembly.

-Matt


0
Reply Matt 1/26/2004 1:35:35 PM

"Bx.C" <null@the.void> wrote in message news:<5_1Rb.37873$DX.20827@bignews3.bellsouth.net>...
> 
> hehe... yah... my A+ instructor told us just the other day that a 586 is
> simply two 486's put together in one package.... (what i think he was
> actually trying to explain at the time, was the fact that the 586 had two
> instruction pipelines.... but he didn't do a very good job.... looking
> around the room, he left the other students more confused than before)...

:-)

That would be a more accurate description of IBMs multicore Power
series, or possibly Intels latest "HyperThreading" technology,
than superscalar processing as applied to the 586.

Oh, and by the way the 486 was pipelined.  Ie. it decodes the
instruction in stages allowing it to overlay the decoding
of instructions -- which is why most instructions have a throughput
of only 1 clock, even though they take several cycles to process.
A basic pipe line would look something like...

   Fetch -- Decode -- Fetch Operands -- Execute -- Write Back

An seperate instruction can be being processed at each stage,
ie. for the above pipeline, up to 5 instructions can be being
processed simultaneously, prodided there are no conflicts.
Conflicts, such as AGI stalls, cause pipeline bubbles.

The 586 (Pentium) was superscalar. Ie. it can execute two
instructions simultaneously (provided they did not conflict
by needing each others resources), this is achieved by having
two pipelines and some nifty logic detect conflicts.

Later processors (686+) are 3-way superscalar 'out-of-order'.
Ie. they can have 3 pipelines and can execute instructions in
a different order to that which the programmer specifies.

I hope this has undone some of the confusion/damage your
instructor inflicted.  Of course, I have attempted to explain
in a few paragraphs what would normally take several chapters,
therefore many details have been elided.  To fill in the many
gaps I suggest you have a look at the book "Hennessy, J., and
Patterson, D. Computer Architecture - A Quantitive Approach.
Morgan Kaufmann Publishers Inc., 1990".  Though it is getting
a little old, it is still the definitive text on the subject.
(I think a second edition was published around 1996.)

C
2004-01-25

0
Reply blackmarlin 1/26/2004 2:45:02 PM

August Derleth <see@sig.now> wrote in message news:<IF1Rb.10471$dF4.2130@fe02.usenetserver.com>...
> I simply didn't realize those little things would have general-purpose 
> programmable logic in them, as opposed to special-purpose circuitry and 
> various amounts of ROM. I know the era of the electromechanical system 
> is over, but has everyone moved from the simple special-purpose chips to 
> the more complex 8051s and such?


The embedded controller market is something like seven billion units
per year.  CPUs intended for the primary computing market ship
something on the order of 150 million units/year.  Also, many of the
controller cores ship embedded in a chip providing application
specific functionality.

It's hard to beat the cost (or flexibility) of small microcontrollers.
 Under a couple of bucks each for a few thousands units gets you a
single chip with RAM, ROM, CPU, and an assortment of interfaces (say
something 8051ish, with 8KB of ROM, a few hundred bytes of RAM, a
couple of dozen I/O pins).  Hard to put much discrete logic on a board
for a couple of bucks.  Of course you can spend considerably more (and
get much more).

0
Reply robertwessel2 1/26/2004 10:47:49 PM

"Beth" <BethStone21@hotmail.NOSPICEDHAM.com> wrote in message
news:YICQb.244$bn3.57@newsfep3-gui.server.ntli.net...
>
> High-level functions:
>     INT 21h, AH = 09h: Print String
>     INT 21h, AH = 0Ah: Buffered Keyboard Input (with echo)
>
> [ These functions deal with complete strings under DOS's control; Easy
> to use but can't be "customised" much so you have to accept however
> DOS deals with the user I/O... ]
>
> Low-level functions:
>     INT 21h, AH = 01h: Keyboard Input with Echo
>     INT 21h, AH = 02h: Display Output
>
>

Your also forgetting

INT 21h, AH = 3Fh
INT 21h, AH = 40h

3F = Read
40 = Write

setting BX
  0 = stdin
  1 = stdout
  2 = stderr

and in fact, MSDOS version past 2,  09 and 01  called 3Fh   and 0A and 02
called 40, so calling 3F and 40 is actually faster than 09 0A 01 02.
Although, you would have to do your own echoing.

Jeremy



0
Reply Dragon 1/27/2004 2:04:33 AM

Dragon Lord wrote:
> Beth wrote:
> >
> > High-level functions:
> >     INT 21h, AH = 09h: Print String
> >     INT 21h, AH = 0Ah: Buffered Keyboard Input (with echo)
> >
> > [ These functions deal with complete strings under DOS's control;
Easy
> > to use but can't be "customised" much so you have to accept
however
> > DOS deals with the user I/O... ]
> >
> > Low-level functions:
> >     INT 21h, AH = 01h: Keyboard Input with Echo
> >     INT 21h, AH = 02h: Display Output
>
> Your also forgetting
>
> INT 21h, AH = 3Fh
> INT 21h, AH = 40h
>
> 3F = Read
> 40 = Write
>
> setting BX
>   0 = stdin
>   1 = stdout
>   2 = stderr

As the question was just "I/O" in general, not necessarily screen
output or keyboard input, then I've "forgotten" an awful lot:

INT 21h, AH = 03h: READ CHARACTER FROM STDAUX
INT 21h, AH = 04h: WRITE CHARACTER TO STDAUX
INT 21h, AH = 05h: WRITE CHARACTER TO PRINTER
INT 21h, AH = 06h: DIRECT CONSOLE I/O
INT 21h, AH = 07h: DIRECT CHARACTER INPUT, WITHOUT ECHO
INT 21h, AH = 08h: CHARACTER INPUT WITHOUT ECHO
INT 21h, AH = 0Ch: FLUSH BUFFER AND READ STANDARD INPUT

.....for starters, which actually contains some more console-style
I/O...but why stop there, when there's also:

INT 21h, AH = 0Fh: OPEN FILE USING FCB
INT 21h, AH = 10h: CLOSE FILE USING FCB
INT 21h, AH = 11h: FIND FIRST MATCHING FILE USING FCB
INT 21h, AH = 12h: FIND NEXT MATCHING FILE USING FCB
INT 21h, AH = 13h: DELETE FILE USING FCB
INT 21h, AH = 14h: SEQUENTIAL READ FROM FCB FILE
INT 21h, AH = 15h: SEQUENTIAL WRITE TO FCB FILE
INT 21h, AH = 16h: CREATE OR TRUNCATE FILE USING FCB
INT 21h, AH = 17h: RENAME FILE USING FCB
INT 21h, AH = 21h: READ RANDOM RECORD FROM FCB FILE
INT 21h, AH = 22h: WRITE RANDOM RECORD TO FCB FILE
INT 21h, AH = 23h: GET FILE SIZE FOR FCB
INT 21h, AH = 24h: SET RANDOM RECORD NUMBER FOR FCB
INT 21h, AH = 25h: SET INTERRUPT VECTOR
INT 21h, AH = 27h: RANDOM BLOCK READ FROM FCB FILE
INT 21h, AH = 28h: RANDOM BLOCK WRITE TO FCB FILE
INT 21h, AH = 2Ch: GET SYSTEM TIME
INT 21h, AH = 2Dh: SET SYSTEM TIME

.....blah-blah-blah...?

Arguably, in fact, practically _every single MS-DOS interrupt_ could
be considered as being some type of "I/O" in one way or another...such
as even "Get System Time" and "Set System Time", at the end of the
list above, are effectively doing "I/O" with the system's time
(reading / writing to it)...

Let me throw you a clue: I, perhaps, was not being exhaustive of every
single DOS interrupt and its complete internal workings (with all the
details and at least one example for all of DOS from top to bottom,
don't expect such a post to appear before 2009 for the length of what
it would be...and you'd probably need to upgrade your hard drive
simply to accomodate the "Library of Congress" it would likely
represent)...

No, what I was doing was trying to "go deep" (in a newbie-relative
way, I'd stress...it won't seem at all "deep" to most out there ;) on
a few selected DOS interrupts to show how they might be used, rather
than "go broad" by throwing up a listing of DOS interrupts (which,
after all, can be got from an awful lot of sources :) and then say
"work it out for yourselves!!!"...

It was intended as a practical way to _get into_ using DOS
interrupts...some actual examples of how they would be used in a
program to get a particular effect...and so on and so forth...that's
what a "newbie" needs at first...of course, once they get the basic
pattern and idea of how it works, then, sure, throw up some list of
all available DOS interrupts and they'll know how it all roughly works
to pick and choose the ones they want...and so on and so
forth...indeed, _after_ reading my post to set the basic pattern and
usage of these things, _then_ your information might, indeed, be
exactly what the newbie wants to know about...

Getting the idea yet? I did not "forget" that there were other DOS
"I/O" interrupts at all...it was simply just never my intention to
cover all of them in a single post...I selected those four as
"representative", as a symmetrical "two sets of two": one is input,
the other output and then each pair is either "low-level" or
"high-level"...because that shows both basic operations in a "let DOS
do it!" way and then showing how you can also take a more "low-level"
interrupt and use your own code to "flesh it out" (and the ability
this provides you to "customise" your "I/O" a little :)...

> and in fact, MSDOS version past 2,  09 and 01  called 3Fh   and 0A
and 02
> called 40, so calling 3F and 40 is actually faster than 09 0A 01 02.
> Although, you would have to do your own echoing.

No doubt; But when writing your first "Hello, world!"-like programs
and getting to grips with how to call DOS interrupts in the first
place - perhaps also, likely at this stage, how to get your assembler
itself working to assemble things - do we care about "fastest"? How
does this information help the newbie at a stage of _not even really
being sure whether "printf" is a machine instruction or not_?

I can see it now: "Good morning, children! Today, our kindergarten
class - after you've drunk your milk and we've dealt with little
Johnny's "accident" - will be counting blocks, colouring in pictures
with crayons...and then posing the ultimate questions of the universe
by conducting high dangerous experiments on elementary particles in a
particle accelerator to probe the nature of Uncertainty Theory, in
order to consider the philosophical and psychological ramifications of
it with respect to the various cosmological models that could wholly
conform to said observations...and, if we've got time after that, we
can sing that song where you all have to do the special hand
actions...won't this be fun, children?" ;)

I have a little rhyme about this, you might want to learn:

"From what you were to what you will become...
You must _learn to walk_ before you can run!"

[ There are also "hand actions" you can do that go along with
it...but, well, one thing at a time, yes? ;) ]

Nevertheless, your information here is valid, interesting and
potentially useful...it's just, well, "Woah, horsey! Woah!"...

Beth :)


0
Reply Beth 1/27/2004 6:52:31 AM

August Derleth wrote:
> I notice you /aren't even using 8088 opcodes/. Post-increment
indexing
> modes? I guess it's the 68000, if it's a microprocessor, but it
could
> (possibly) be a PDP or a VAX.
>
> I'm aware that this was cross-posted to alt.lang.asm. But why would
you
> hype V86 and other Intel things if your code wasn't even going to be
for
> Intel chips?

Just for clarification, Herbert's got some very weird habits and
opinions...of which, you've just met one of the weirdest...

Herbert has written himself an x86 assembler which uses
Motorola-inspired syntax...yes, the code you were looking at there
_IS_ x86 code...but he's changed around the syntax to make it look
like 68K code...for example, something like "trap #$21" would be "int
21h" in the more conventional Intel syntax...

[ And, with priceless irony, Herbert has been known to complain about
HLA..._because_ of its "non-standard" syntax!! Three words come to
mind: "pot", "kettle" and "black"...it's quite ludicrous,
really...Randy just adds brackets and swaps the operands around in a
few cases and this is apparently so "non-standard" as to be "the evil
spawn of satan" or something...yet, using syntax from a completely
different architecture altogether - the 68K series, which has
_fundamental differences_ like endianness and "data / address"
registers and so forth - is completely okay and not in the slightest
bit confusing for Herbert to be posting to x86 forums!! ]

Don't worry too much about Herbert's opinions, as they all seem to
boil down to: "If you're not programming your code using a soldering
iron and oscillascope against the bare metal of the motherboard
itself, then you're not really programming at all!"...for example, he
creates all his Windows PE files manually by using "DB" to define all
the headers because the use of a linker is probably some "evil spawn
of satan" thing in his own mind...

You were on the money, August, with that "dick waving" machismo
comment...I mean, he may claim that his 68K-inspired syntax is all
about "Motorola have a cleaner syntax" but, in the end, we _ALL KNOW_
that it's really a case of: "Look how hard I am! I can use totally
confusing syntax! I know more than one assembly language, as you can
see, so I'm a really hard guru-type person!"...and all that kind of
nonsense...thus, his opinions as to what is best for a beginner to use
are, as you've rightly pointed out, hardly things to take all that
seriously: "beginners should eat steel nails and pour raw coffee down
their throats or they are just wimps!! And there's only room for 'hard
men' in assembly programming!!" ;)

Beth :)


0
Reply Beth 1/27/2004 7:37:17 AM

Matt Taylor wrote:
> Since when? That is automatically provided to you unless you hexedit
your
> own executable.

Exactly; Herbert _DOES_ hexedit his own PE executable files (using a
68K-inspired syntax, even though it's on an x86, even!)...

He insists that you're not doing "real assembly" (whatever that
implies) unless you "DB" all your headers manually...of course, what
knowing the format of the OS-specific Microsoft PE file format has got
to do with comprehending the workings of an x86 chip, goodness
knows...but this is Herbert's logic and, apparently, beginners aren't
learning anything at all and aren't "real" macho coders (and if you're
not a "macho coder" like Herbert then you aren't even a blip on his
radar, as far as he's concerned), unless they also follow this often
rather bizarre logic he has...

Beth :)


0
Reply Beth 1/27/2004 7:55:24 AM

Beth wrote:
 
> Don't worry too much about Herbert's opinions, as they all seem to
> boil down to: "If you're not programming your code using a soldering
> iron and oscillascope against the bare metal of the motherboard
> itself, then you're not really programming at all!"...for example, he
> creates all his Windows PE files manually by using "DB" to define all
> the headers because the use of a linker is probably some "evil spawn
> of satan" thing in his own mind...

Beth, you still didn't get the point. We are talking about 
learning assembly programming and not about writing applications
in assembler (nearly nobody does this in these days). Pupils
still learn to add/sub/mul/div using their brain and a pencil
even if they later only use a pocket calculator. They learn to 
write with a pencil and to spell words and later only use a
keyboard and a spell checker. If you learn a trade, you still
have to learn how things are done manually even though later you
will never do this again because it is done by a machine.

And the same is true for learning assembly programming.
You should do all things at the lowest level to understand
what happens. Once you have understood it, you don't need to
do it again, use a compiler/linker and libraries to do the 
work for you.


PS: Did you ever see the bootstrap code of a PDP11/45 realized
    with a diode matrix on a PCB. That's "programming your code 
    using a soldering iron".

0
Reply Herbert 1/27/2004 4:55:42 PM

"C" <blackmarlin@asean-mail.com> wrote in message
news:33d97ee5.0401260642.18bd5e4f@posting.google.com...
> "Bx.C" <null@the.void> wrote in message
news:<5_1Rb.37873$DX.20827@bignews3.bellsouth.net>...
> >
> > hehe... yah... my A+ instructor told us just the other day that a 586 is
> > simply two 486's put together in one package.... (what i think he was
> > actually trying to explain at the time, was the fact that the 586 had
two
> > instruction pipelines.... but he didn't do a very good job.... looking
> > around the room, he left the other students more confused than
before)...
>
> :-)
>
> That would be a more accurate description of IBMs multicore Power
> series, or possibly Intels latest "HyperThreading" technology,
> than superscalar processing as applied to the 586.
>
> Oh, and by the way the 486 was pipelined.  Ie. it decodes the
> instruction in stages allowing it to overlay the decoding
> of instructions -- which is why most instructions have a throughput
> of only 1 clock, even though they take several cycles to process.
> A basic pipe line would look something like...
>
>    Fetch -- Decode -- Fetch Operands -- Execute -- Write Back
>
> An seperate instruction can be being processed at each stage,
> ie. for the above pipeline, up to 5 instructions can be being
> processed simultaneously, prodided there are no conflicts.
> Conflicts, such as AGI stalls, cause pipeline bubbles.
>
> The 586 (Pentium) was superscalar. Ie. it can execute two
> instructions simultaneously (provided they did not conflict
> by needing each others resources), this is achieved by having
> two pipelines and some nifty logic detect conflicts.
>
> Later processors (686+) are 3-way superscalar 'out-of-order'.
> Ie. they can have 3 pipelines and can execute instructions in
> a different order to that which the programmer specifies.
>
> I hope this has undone some of the confusion/damage your
> instructor inflicted.  Of course, I have attempted to explain
> in a few paragraphs what would normally take several chapters,
> therefore many details have been elided.  To fill in the many
> gaps I suggest you have a look at the book "Hennessy, J., and
> Patterson, D. Computer Architecture - A Quantitive Approach.
> Morgan Kaufmann Publishers Inc., 1990".  Though it is getting
> a little old, it is still the definitive text on the subject.
> (I think a second edition was published around 1996.)
>
> C
> 2004-01-25
>

yes, but i must say... i seriously doubt the rest of my A+ class are ready
for this info..... i tried having a logical technical discussion about the
relevance of Microsoft DOS in current and future operating systems (while
keeping in mind that v86 sessions won't run in Long mode on 64-bit
processors).... and while i myself debated both ways... that Microsoft would
keep some form of DOS, even while running under the most secure modes of
later processors, but may re-work it to be a simple 32-bit command line
interface run under protected mode only, leaving out the possibility for
switching between v86 sessions and 64-bit mode... which would be a very
nasty job to keep track of, trying to jump back and forth constantly... (and
yet, they may keep the current real mode or v86 mode compatible DOS simply
for pre-winboot tasks.... disk maintenance... registry repair... password
recovery... etc)    ..... the person i was sitting with, discussing this
with... seemed lost in the first few minutes...

and right now.... looking back... i think i had too much coffee this
morning...




0
Reply Bx 1/27/2004 5:12:21 PM

Having more resources isn't bad.  Not only that, these interrupts would be
more understandable come from say... a unix platform, or C++ background.
cin, cout, cerr can be simulated this way.  Also, explaining to users the
different approaches, allows the user to decide which is best for the
situation in which they are writing it for.  You make it sound even bad to
come up with alternatives.  Also, I don't think the console channels end up
in FCB, so 0F-17 and 21-28.  But as I was just showing SOME alternatives,
you could also use IN and OUT to get your data if your really daring.



0
Reply Dragon 1/27/2004 9:10:52 PM

Beth wrote:
> August Derleth wrote:
> 
>>I notice you /aren't even using 8088 opcodes/. Post-increment
> 
> indexing
> 
>>modes? I guess it's the 68000, if it's a microprocessor, but it
> 
> could
> 
>>(possibly) be a PDP or a VAX.
>>
>>I'm aware that this was cross-posted to alt.lang.asm. But why would
> 
> you
> 
>>hype V86 and other Intel things if your code wasn't even going to be
> 
> for
> 
>>Intel chips?
> 
> Herbert has written himself an x86 assembler which uses
> Motorola-inspired syntax...yes, the code you were looking at there
> _IS_ x86 code...but he's changed around the syntax to make it look
> like 68K code...for example, something like "trap #$21" would be "int
> 21h" in the more conventional Intel syntax...

Oh, ok. It is just him. I was wondering who would make and market an x86 
assembler with 68000 syntax, and who would be bizarre enough to 
buy/download it. Knowing it's a homebrew makes more sense, in that I 
only have to posit /one/ weirdo to make it happen. ;)

> 
> [ And, with priceless irony, Herbert has been known to complain about
> HLA..._because_ of its "non-standard" syntax!! Three words come to
> mind: "pot", "kettle" and "black"...it's quite ludicrous,
> really...Randy just adds brackets and swaps the operands around in a
> few cases and this is apparently so "non-standard" as to be "the evil
> spawn of satan" or something...yet, using syntax from a completely
> different architecture altogether - the 68K series, which has
> _fundamental differences_ like endianness and "data / address"
> registers and so forth - is completely okay and not in the slightest
> bit confusing for Herbert to be posting to x86 forums!! ]

HLA's syntax isn't something I particularly enjoy, but it's a sight more 
readable to the casual reader than Herbert's code. (I'm a 
dyed-in-the-wool nasm lover, and so I disagree with Randy on a few 
issues related to what an assembler should be expected to do, which goes 
quite a bit deeper than syntax. But at least we both agree on what the 
int opcode should be called. :) )

> 
> Don't worry too much about Herbert's opinions, as they all seem to
> boil down to: "If you're not programming your code using a soldering
> iron and oscillascope against the bare metal of the motherboard
> itself, then you're not really programming at all!"...for example, he
> creates all his Windows PE files manually by using "DB" to define all
> the headers because the use of a linker is probably some "evil spawn
> of satan" thing in his own mind...

Yeah. I was wondering just what made his 32-bit examples so damned huge. 
I didn't take the time to realize the yahoo was /writing his own headers/.

For someone who thinks beginners should start on the simple stuff, this 
takes the cake: If he thinks the only way to write code for an OS that 
doesn't accept flat-binary executables (that is, all modern OSes except 
the last remaining DOS clones) is to roll your own headers, how does he 
expect beginners to /ever/ write 32-bit assembly? Does he want them to 
stick with V86 DOS mode until they can convince themselves to write 
their own headers each time?

Bah. What a loon.

> 
> You were on the money, August, with that "dick waving" machismo
> comment...I mean, he may claim that his 68K-inspired syntax is all
> about "Motorola have a cleaner syntax" but, in the end, we _ALL KNOW_
> that it's really a case of: "Look how hard I am! I can use totally
> confusing syntax! I know more than one assembly language, as you can
> see, so I'm a really hard guru-type person!"...and all that kind of
> nonsense...thus, his opinions as to what is best for a beginner to use
> are, as you've rightly pointed out, hardly things to take all that
> seriously: "beginners should eat steel nails and pour raw coffee down
> their throats or they are just wimps!! And there's only room for 'hard
> men' in assembly programming!!" ;)

I'm a fan of Motorola's 68k architecture. Hell, I'm a fan of Digital's 
(now Compaq's) PDP and VAX architectures, may they rest in peace. But as 
much as I'd want to own a 68k-based home machine (or maybe a nice VAX... 
;) ), I own an AMD Duron and so I write assembly for an x86 clone. I 
don't try to fool myself with a syntax that doesn't fit the architecture.

I'm not saying Herbert doesn't have a right to use whatever syntax he 
wants, but in this newsgroup it's rather rude to use something so 
bizarre it needs explanation every time it's trotted out. Especially if 
you never fully explain it. (For example, how do registers work on his 
system? Is r0 the name of ah, ax, or eax? If r0 is ax or eax, how does 
he access ah and al seperately? See what I mean about fooling with a 
syntax that doesn't fit the architecture?)

> 
> Beth :)
> 
> 


-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/27/2004 11:47:30 PM

"Bx.C" <null@the.void> wrote in message
news:lTjRb.28647$lh3.19975@bignews5.bellsouth.net...
<snip>
> yes, but i must say... i seriously doubt the rest of my A+ class are ready
> for this info..... i tried having a logical technical discussion about the
> relevance of Microsoft DOS in current and future operating systems (while
> keeping in mind that v86 sessions won't run in Long mode on 64-bit
> processors).... and while i myself debated both ways... that Microsoft
would
> keep some form of DOS, even while running under the most secure modes of
> later processors, but may re-work it to be a simple 32-bit command line
> interface run under protected mode only, leaving out the possibility for
> switching between v86 sessions and 64-bit mode... which would be a very
> nasty job to keep track of, trying to jump back and forth constantly...
(and
> yet, they may keep the current real mode or v86 mode compatible DOS simply
> for pre-winboot tasks.... disk maintenance... registry repair... password
> recovery... etc)    ..... the person i was sitting with, discussing this
> with... seemed lost in the first few minutes...

They wrote an x86 emulator back when NT was first written. Back then, RISC
architectures were expected to displace x86, and they needed backward
compatibility. As I understand, 64-bit Windows will use this emulator to
emulate DOS/Win16.

> and right now.... looking back... i think i had too much coffee this
> morning...

Impossible!

-Matt


0
Reply Matt 1/28/2004 2:26:10 AM

"Matt Taylor" <para@tampabay.rr.com> wrote:
>
>They wrote an x86 emulator back when NT was first written. Back then, RISC
>architectures were expected to displace x86, and they needed backward
>compatibility. As I understand, 64-bit Windows will use this emulator to
>emulate DOS/Win16.

Actually, it appears that 64-bit Windows simply will not support DOS or
Win16 apps.  I made a statement about this in one of the MVP newsgroups,
and a fellow who was running a Win64 system did a couple of experiments for
me that seemed to confirm this.

I was surprised, since I would guess the incremental cost of DOS/Win16
support to be near nil.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 1/28/2004 6:50:20 AM

On Tue, 27 Jan 2004 23:47:30 +0000 (UTC), August Derleth <see@sig.now> wrote:

[...]

>I'm not saying Herbert doesn't have a right to use whatever syntax he 
>wants,

Perish the thought.

> but in this newsgroup it's rather rude to use something so 
>bizarre

<g>

> it needs explanation every time it's trotted out.

And on top of that, use it as an "example" illustrating why assembler
for Windows is a bad idea.

> Especially if 
>you never fully explain it.

Honestly, does it matter?  I mean... beyond a certain point--and it's a
point which lies very near the starting line--does it really frickin' matter...

"Hey, it might be silly, but it makes no sense!"  ;)

Arguing for the sake of arguing... is there a specific word for that?  A
thoroughly unlovely conglomeration... sophistic, argumentative, contentious
wrangling...  needs its own word.

Jeff

http://www.jefftturner.com



0
Reply pH 1/28/2004 4:32:08 PM

On Mon, 26 Jan 2004 05:26:41 +0000 (UTC), Bjarni Juliusson
<bjarni.ferret@update.ferret.uu.se> wrote:

>I'm in the mood for a little nitpicking.
>
>> Intel started long ago with the 4040, which was used only in
>
>They started with the world's first microprocessor, the 4004, in 1971. 
>Development had started in 1969. It was a 4 bit chip. In 1972 Intel 
>introduced the 8 bit 8008.
>
>> calculators.  Later, the 8080 was designed and used in CP/M based
>
>Correct. This was in 1974. The 8080 was an 8 bit processor with 16 bit 
>addresses, and it was the model for the incredibly popular Z80.
>
>> systems, then came along the 8088 (and soon after 8086), which was
>> used on PC's, XT's, and clones.  These systems used 16-bit
>> instructions on what was an 8-bit CPU (or in the case of the 8086 a
>> 16-bit cpu with an 8-bit bus), and in order to access more memory than
>
>Very common mistake. The 8086 was released in 1978, and it is a true 16 
>bit processor. To allow for cheaper circuit boards, Intel released the 
>8088 in 1979. This is an exact copy of the 8086, but with an 8 bit 
>external data bus. It is a 16 bit processor inside, just like the 8086.
>
>> possible with a single 16-bit register, Intel used segment:offset
>> scheme of doing things.  The segment was shifted 4 bits and added to
>> the offset to point to the actual memory location.  This meant that
>> any given memory location could be referenced in several different
>> ways, eg.
>
Somewhere about here came the 80186 & 88.

>Now this is all true. Then came the 80286 with 16 bit protected mode, 
>then the 80386 with 32 bit protected mode, and the rest have essentially 
>been fast 386s.

-- 
Arargh401 at [drop the 'http://www.' from ->] http://www.arargh.com
BCET Basic Compiler Page: http://www.arargh.com/basic/index.html

To reply by email, remove the garbage from the reply address.

0
Reply arargh401NOSPAM 1/28/2004 9:49:27 PM

Frank Kotler wrote:
> Beth wrote:
> 
>> You were on the money, August, with that "dick waving" machismo
>> comment...
> 
> 
> No he wasn't! (in my ever-so-humble opinion, of course!) I knew you'd be 
> attracted to that phrase, Beth. If my dick were as small as my .com 
> files, I'd keep it in my pants where it belongs!

/This/ brings up odd images. I suppose I initiated the whole `dick 
size'/`binary size' thing, but it doesn't make much sense.

> 
> Seriously, this "executable size doesn't matter because Windows wastes 
> memory/storage in big chunks anyway" doesn't wash. To be sure, cutting 
> your "hello world" from 30 bytes to 27 doesn't make any difference, but 
> cutting ten percent off your megabyte executable *does*!

I never mentioned Windows. Linux, with its ext2 filesystem, allocates 
disk space in chunks no smaller than one Kibibyte (1024 bytes), and 
usually something like four Kibibytes. (I don't think ext3 changes this 
basic philosophy.) Why? Because disk access is slow, and RAM is fast. If 
you can shove relatively large blocks of the disk into RAM at once and 
thereafter access RAM, you can get big wins in performance. There's no 
way in hell a modern non-embedded OS is going to access the disk for 
anything less than one Kib, even if it means wasting both RAM and disk 
space.

Now that that's off my chest...

Shaving ten percent off a multi-Meb executable is perhaps laudible, but 
Moore's Law or something very like it applies to disks, too. You shrink 
the size of the program from five Mebs (5,242,880 bytes) to 4.9 Mebs 
(4,718,592 bytes). Meanwhile, your client is buying 120 Gibibyte* hard 
drives for his machines, and your size saving gets lost in the underflow.

*That's 120 * 2**30, an eleven-digit number. I own one, and I haven't 
even been able to quarter-fill it in over a year of trying. ;) I can 
safely say I now own a storage device whose capacity is beyond my 
comprehension.

> 
> If the professionals wrote software with a "don't care about size" 
> attitude like that, we'd see... Oh. Right. Nevermind...

Usually, it doesn't matter. That doesn't mean people should be lazy 
about these things: Quite the opposite, it means that people should use 
the techniques that will give the best /balance/ between the various 
factors in program development. And raw size is usually /not/ a 
heavily-weighted factor, especially when compared to future 
maintainability and security. Or, to drag this back to the original 
tangent, ease of using the code to teach students of assembly language.

Since I'm not convinced Microsoft has mastered /any/ of those things 
(bloat control, maintainability, or security, among other important 
factors), I will laugh at your little joke. :D

Now for a little aside and confession: When I'm writing assembly, I will 
go back and optimize for size and speed even after I've decided the 
program is done, finished, and completed. (Needless to say, these are my 
own personal programs I'm messing with.) I'll replace things like
   mov eax, 0FFFFFFFFh
with
   xor eax, eax
   dec eax
simply because I can't stand to see 32 bits simply used to store a 
constant value. I've never gotten into cycle-counting, partly because my 
knowledge would be obsolete before it's mastered and partly because I 
don't want to rewrite all of my programs /again/. ;)

> 
> Best,
> Frank
> 
> 


-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/30/2004 6:58:51 PM

August Derleth <see@sig.now> wrote in message news:<nnsSb.522$rK6.228@fe02.usenetserver.com>...
 I'll replace things like
>    mov eax, 0FFFFFFFFh
> with
>    xor eax, eax
>    dec eax


"OR EAX, -1" is better (encoded as 83C8FF).
It is the same length, but is executed as
only one instruction and therefore can pair
better. :-)

C
2004-01-30

0
Reply blackmarlin 1/30/2004 11:13:15 PM

Tim Roberts wrote:

> "Matt Taylor" <para@tampabay.rr.com> wrote:
> 
>>They wrote an x86 emulator back when NT was first written. Back then, RISC
>>architectures were expected to displace x86, and they needed backward
>>compatibility. As I understand, 64-bit Windows will use this emulator to
>>emulate DOS/Win16.
> 
> 
> Actually, it appears that 64-bit Windows simply will not support DOS or
> Win16 apps.

And Linux does and will. Well, I don't know about Win16. dosemu is 
focused on 16/32-bit textmode DOS, and WINE is Win32-only so far as I 
know. But a small convergence between the virtual machine folks (dosemu) 
and the API folks (WINE) should fill the gap fairly well.

(Oh, and note that neither dosemu nor WINE do actual emulation. They 
both let the x86 CPU they assume the hardware machine has execute the 
opcodes, and fill in details like establishing the API and, if the 
software wants it, V86 mode.* If you want emulation, you need Bochs. 
Maybe IA-64 will require something like Bochs to execute IA-16/32 code.)

*(In fact, Linux has a syscall to shift a specific process into V86 
mode. So far as I know, only dosemu uses it.)

-- 
My address is yvoregnevna gjragl-guerr gjb-gubhfnaq guerr ng lnubb qbg pbz
Note: Rot13 and convert spelled-out numbers to numerical equivalents.

0
Reply August 1/31/2004 5:17:37 AM

On Tue, 27 Jan 2004 17:12:21 +0000 (UTC), "Bx.C" <null@the.void>
wrote:

>> > hehe... yah... my A+ instructor told us just the other day that a 586 is
>> > simply two 486's put together in one package.... (what i think he was
>> > actually trying to explain at the time, was the fact that the 586 had
>two
>> > instruction pipelines.... but he didn't do a very good job.... looking
>> > around the room, he left the other students more confused than
>before)...
Just one small reason why I usually consider A+ and MSCE
certifications worthless.... Anyone flashing an A+ or MSCE
certification to me gives me the impression they don't know anything
and are relying on paying someone some money to say they passed the
exam.  But then again, maybe if you seen "What" passes the A+ and MSCE
exams in these parts and can't understand how to configure a computer,
install windows, etc...  Not to put the other guy down, just that I've
had to straighten out too much work from idiots who flash a MSCE
certificate and A+ certificate making people think they know what
they're doing.... 

0
Reply John 1/31/2004 7:42:34 PM

On Mon, 26 Jan 2004 05:26:41 +0000 (UTC), Bjarni Juliusson
<bjarni.ferret@update.ferret.uu.se> wrote:

>Correct. This was in 1974. The 8080 was an 8 bit processor with 16 bit 
>addresses, and it was the model for the incredibly popular Z80.
O.k. so I transposed a couple of numbers on the 4004 and left out the
8008.... ;-)

>> systems, then came along the 8088 (and soon after 8086), which was
>> used on PC's, XT's, and clones.  These systems used 16-bit
>> instructions on what was an 8-bit CPU (or in the case of the 8086 a
>> 16-bit cpu with an 8-bit bus), and in order to access more memory than
>
>Very common mistake. The 8086 was released in 1978, and it is a true 16 
>bit processor. To allow for cheaper circuit boards, Intel released the 
>8088 in 1979. This is an exact copy of the 8086, but with an 8 bit 
>external data bus. It is a 16 bit processor inside, just like the 8086.
As I said, the 8086 was a 16-bit CPU, but it very much had an 8-bit
BUS to all other chips.  It was not a TRUE 16-bit processor, as a true
16-bit processor would have a 16-bit data path everywhere....

>> possible with a single 16-bit register, Intel used segment:offset
>> scheme of doing things.  The segment was shifted 4 bits and added to
>> the offset to point to the actual memory location.  This meant that
>> any given memory location could be referenced in several different
>> ways, eg.
>
>Now this is all true. Then came the 80286 with 16 bit protected mode, 
>then the 80386 with 32 bit protected mode, and the rest have essentially 
>been fast 386s.
Yes, I could have swore I mentioned protected mode in the original
message...

0
Reply John 1/31/2004 7:42:58 PM

"August Derleth" <see@sig.now> wrote in message
news:7HFSb.240$JA.49@fe02.usenetserver.com...
> Tim Roberts wrote:
>
> > "Matt Taylor" <para@tampabay.rr.com> wrote:
> >
> >>They wrote an x86 emulator back when NT was first written. Back then,
RISC
> >>architectures were expected to displace x86, and they needed backward
> >>compatibility. As I understand, 64-bit Windows will use this emulator to
> >>emulate DOS/Win16.
> >
> >
> > Actually, it appears that 64-bit Windows simply will not support DOS or
> > Win16 apps.
>
> And Linux does and will. Well, I don't know about Win16. dosemu is
> focused on 16/32-bit textmode DOS, and WINE is Win32-only so far as I
> know. But a small convergence between the virtual machine folks (dosemu)
> and the API folks (WINE) should fill the gap fairly well.

They're going to have to use a different strategy in long mode. Long mode
does not support v8086 mode.

> (Oh, and note that neither dosemu nor WINE do actual emulation. They
> both let the x86 CPU they assume the hardware machine has execute the
> opcodes, and fill in details like establishing the API and, if the
> software wants it, V86 mode.* If you want emulation, you need Bochs.
> Maybe IA-64 will require something like Bochs to execute IA-16/32 code.)
<snip>

Itanium actually has a mode to emulate IA-32, but it's absolutely awful. I
have heard that Merced could execute IA-32 code about as fast as a 486.
Windows for IA-64 emulates IA-32 code now.

-Matt


0
Reply Matt 1/31/2004 8:59:21 PM

On Sat, 31 Jan 2004 19:42:58 +0000 (UTC), "John H. Guillory"
<johng@mlc-hosting.net> wrote:

>As I said, the 8086 was a 16-bit CPU, but it very much had an 8-bit
>BUS to all other chips.  It was not a TRUE 16-bit processor, as a true
>16-bit processor would have a 16-bit data path everywhere....

The 8086 was a true 16-bit processor, with a 16-bit bus.  You are
thinking of the 8088, which was identical internally but only had
an 8-bit bus.  IBM chose this for cost reasons; the 8086 was never
a success itself.   Incidentally, the same short-bus idea was
resurrected when 32 bits came out, in the form of the 386SX;
you had to get a 386DX to get a 32-bit bus.   The SX monniker
was later applied to the 486 to indicate it was missing the NPU,
even though the bus was the full 32 bits.  






Bob Masta
dqatechATdaqartaDOTcom
 
            D A Q A R T A
Data AcQuisition And Real-Time Analysis
           www.daqarta.com

0
Reply NoSpam 2/1/2004 3:16:02 PM

> I hope this has undone some of the confusion/damage your
> instructor inflicted.  Of course, I have attempted to explain
> in a few paragraphs what would normally take several chapters,
> therefore many details have been elided.  To fill in the many
> gaps I suggest you have a look at the book "Hennessy, J., and
> Patterson, D. Computer Architecture - A Quantitive Approach.
> Morgan Kaufmann Publishers Inc., 1990".  Though it is getting
> a little old, it is still the definitive text on the subject.
> (I think a second edition was published around 1996.)

There was even a third edition in 2003.


-- 
Remove the furry animal from my address to send email:

   bjarni.ferret@update.ferret.uu.se

0
Reply Bjarni 2/1/2004 10:24:51 PM

On Sun, 25 Jan 2004 +0000 (UTC), August Derleth <see@sig.now> wrote:
>Herbert Kleebauer wrote:
>> August Derleth wrote:
>>>Herbert Kleebauer wrote:
>> 
>>>>But even if an Intel 32 bit processor is used, a beginner always
>>>>should start learning assembly programming in real or V86 mode and
>>>>not in protected mode.
>>>
>>>Should all new drivers start out with a Model-T, too? 
>> 
>> 
>> I didn't speak of an ancient 8086 processor. Even the newest x86 processor
>> supports the three modes: real/V86/protected mode. And you can use the 
>> 32 bit instructions and all the 32 bit addressing modes in any of this
>> three modes. So it doesn't matter at all which of this modes you use to
>> LEARN assembly programing. But it is important to use an operating 
>> system with a simple interface so you can concentrate on the language
>> of the processor and don't have to spend much more time with the OS 
>> interface than with the processor instructions. And the int21
>> interface is much easier to use (and still supported in the newest
>> MS operating systems for V86 mode) than the Win32 interface.

[]

>And if you are using the 32-bit addressing modes and opcodes in V86 
>mode, why not drop the last pretenses of `simplicity' and move into 
>32-bit protected mode? It really isn't that difficult, and it can save 
>you from shooting yourself in the foot: In protected mode, it becomes 
>impossible to scribble on memory you don't own. What could have been an 
>OS-corrupting error becomes a much easier to understand segfault error 
>on Linux, for example, because Linux has nothing to do with V86. (Linux 
>has a syscall to move a specific process into V86 mode, which to my 
>knowledge is only used by one program: dosemu, the virtual x86 system 
>capable of hosting a DOS-like OS plus BIOS. Other than that, Linux is 
>just another Unix.)

So why, in Linux, programs with ID=0 would not read or write in others
memory programs? Only for processor reasons?

>/Au contraire/: Assembly isn't a stand-alone language anymore in most 
>cases. Interfacing with an HLL (and I don't know how HL C is ;) ) is not 
>only an exercise in simplicity (via libc), it's practice in how to 
>structure your own subroutines (learn which registers you must save, 
>learn how to create and destroy a stack frame, learn how to access 
>arguments, and learn how to properly return a value) and create your own 
>libraries.
>
>Learning the instruction set isn't hard.

I think there are too instructions [and too instructions that do the
same thing] even in 8086cpu; I can full program use 20% of
instructions

>Learning memory is more 
>difficult, but 32-bit protected mode makes it easier in addition to 
>giving you a nice net. Learning how to structure a program logically and 
>how to write consistent code that makes use of the environment is more 
>difficult, and it isn't something DOS is especially good at teaching.

I like 8086 asm programming more than 80x86  (x>=1) programming
perhaps it is because I can mix code and data. I think that 8086 is
better planed but this is the first impression of a newbie

>>>>As an example a simple program which reads from stdin and writes
>>>>to stdout, converting all upper case characters to lower case.
>>>>To make it compatible with the win32 version, it uses mostly
>>>>32 bit instructions. But even then the generated executable
>>>>file size is only 109 bytes.
>>>
>>>Executable size? Dick-waving nonsense. Blocks on a hard drive are larger
>>>than that. You gain nothing by stripping the binary to less than one or
>>>two Kibibytes.

I **not agree** for principle

>> You are right, it doesn't matter how much disc space is needed for
>> a program. But we are speaking about learning assembly programming.
>> And it does matter if a beginner has to understand 1000 or only 100
>> bytes to successfully run his first assembler program.

0
Reply RoWsRaIrTiEo 2/16/2004 6:32:23 PM

RoWsRaIrTiEo   <non@esist.eeee> wrote:
>
>So why, in Linux, programs with ID=0 would not read or write in others
>memory programs? Only for processor reasons?

Oh, they certainly CAN do so, although it is a lot of work.

Page tables are swapped when a process changes, so the pages belonging to
other processes are no longer in the page tables.  The pages are still in
memory, but they are temporarily "orphaned".  A suitably motivated
user-mode root process could certainly scan the system to figure out what
physical pages belong to other processes and write on them, but there are
so many other interesting and pesky things one can do in a root process
that this just isn't worth the trouble.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 2/17/2004 4:54:07 AM

On Mon, 16 Feb 2004 18:32:23 +0000 (UTC), RoWsRaIrTiEo
<non@esist.eeee> wrote:

>
>I like 8086 asm programming more than 80x86  (x>=1) programming
>perhaps it is because I can mix code and data. I think that 8086 is
>better planed but this is the first impression of a newbie


It is perfectly possible to mix code and data on any x86 system.
In the DOS days there was a strong incentive *not* to mix them
on programs above 64K in size, since you could typically keep
all your data in one data segment and access it from your code
segment(s).  Or you could keep different data in different data
segments if you really had a lot, and just change DS (or ES) as
needed.

In 32-bit protected mode programming you are effectively mixing
code and data, since there is only one huge memory space, and
all the segment selectors are set the same (on Windows, anyway).
By default your assembler expects you to declare your data and
code in separate sections, but they can be easily combined if
you have some need to do so.  (One reason might be self-modifying
code for security purposes.)   You now have a much bigger sandbox
to play in, and those wonderful 32-bit wide instructions at no extra
(prefix) cost!

 
Bob Masta
dqatechATdaqartaDOTcom
 
            D A Q A R T A
Data AcQuisition And Real-Time Analysis
           www.daqarta.com

0
Reply NoSpam 2/17/2004 1:35:59 PM

"Bob Masta" <NoSpam@daqarta.com> wrote in message
news:40321562.1402124@news.itd.umich.edu...
> On Mon, 16 Feb 2004 18:32:23 +0000 (UTC), RoWsRaIrTiEo
> <non@esist.eeee> wrote:
>
> >
> >I like 8086 asm programming more than 80x86  (x>=1) programming
> >perhaps it is because I can mix code and data. I think that 8086 is
> >better planed but this is the first impression of a newbie
>
>
> It is perfectly possible to mix code and data on any x86 system.
> In the DOS days there was a strong incentive *not* to mix them
> on programs above 64K in size, since you could typically keep
> all your data in one data segment and access it from your code
> segment(s).  Or you could keep different data in different data
> segments if you really had a lot, and just change DS (or ES) as
> needed.
>
> In 32-bit protected mode programming you are effectively mixing
> code and data, since there is only one huge memory space, and
> all the segment selectors are set the same (on Windows, anyway).
> By default your assembler expects you to declare your data and
> code in separate sections, but they can be easily combined if
> you have some need to do so.  (One reason might be self-modifying
> code for security purposes.)   You now have a much bigger sandbox
> to play in, and those wonderful 32-bit wide instructions at no extra
> (prefix) cost!
>

from a memory access point of view, though... isn't the L1 cache separated
into a code cache and a data cache? (or is my mind fried from too much
nintendo? or both?)

0
Reply Bx 2/17/2004 7:13:50 PM

56 Replies
751 Views

(page loaded in 0.929 seconds)

Similiar Articles:


















7/23/2012 1:41:31 PM


Reply: