Chapter16
A program with no include files
TITLE Simple (Simple.asm)
.model small,stdcall
.stack 100h ;;256 bytes of stack space for this or other prgrams to use
.data
msg1 db "simple assembly example",0dh,0ah,'$'
.code
main PROC
mov ax,@data
mov ds,ax
mov dx,offset msg1
mov ah,9
int 21h
mov ax,4c00h
int 21h
main ENDP
END main
Running simple without batch file:
DOS screen
C:\MASM615>ml simple.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: simple.asm
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Object Modules [.obj]: simple.obj
Run File [simple.exe]: "simple.exe"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:
C:\MASM615>simple
simple assembly example
C:\MASM615>
Invoking the assembler and linker
separately
• By invoking the assembler (ml.exe) using
masm.exe and the linker (link) separately, you
can define the name of the exe and other output
files instead of using default naming.
• You can also link multiple modules into a single
executable using:
Link modA ModB modC
• Where the first file named will be the “main”
Running simple without batch file:
DOS screen, version 2…
C:\MASM615>masm simple
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c simple.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: simple.asm
C:\MASM615>link simple
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Run File [simple.exe]:
List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
C:\MASM615>simple
simple assembly example
Explicit segment definition: running
explicit
C:\MASM615>masm explicit
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c explicit.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: explicit.asm
C:\MASM615>
C:\MASM615>link explicit
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Run File [explicit.exe]:
List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
C:\MASM615>explicit
simple assembly example
Explicit.asm
TITLE Explicit (Explicit.asm)
CSEG SEGMENT 'CODE'
ASSUME CS:CSEG,DS:DSEG,SS:SSEG
main PROC
mov ax,DSEG
mov ds,ax
mov dx,offset msg1
mov ah,9
int 21h
mov ax,4c00h
int 21h
main ENDP
CSEG ENDS
SSEG SEGMENT PARA STACK 'STACK'
byte 100 dup(0)
SSEG ENDS
DSEG SEGMENT 'DATA'
msg1 db "simple assembly example",0dh,0ah,'$'
DSEG ENDS
END main
About ASSUME
• The assume directive does not point
registers (ds, es) where they are supposed
to go. The programmer must still do that.
• It tells the assembler to assemble code
assuming that’s where the segments will
be.
Multiple code segments
• A call to a proc in a different code segment
is a far call, requiring both cs and ip be
saved (pushed), changed to point to the
called proc, then recovered (popped). Of
course the system does the pushing and
popping.
• The programmer must define procs as far
when appropriate.
Multcode example from text: note far proc
TITLE Multiple Code Segments
(MultCode.asm)
.model small,stdcall
.stack 100h
WriteString PROTO
.data
msg1 db "First Message",0dh,0ah,0
msg2 db "Second Message",0dh,0ah,"$"
.code
main PROC
mov ax,@data
mov ds,ax
mov dx,OFFSET msg1
call WriteString
; NEAR call
call Display
; FAR call
.exit
main ENDP
.code OtherCode
Display PROC FAR
mov ah,9
mov dx,offset msg2
int 21h
ret
Display ENDP
END main
Assemble and run…
C:\MASM615>make16 multcode
Assembling: multcode.asm
Volume in drive C has no label.
Volume Serial Number is 07D2-0208
Directory of C:\masm615
11/29/2006 01:09 PM
457 MultCode.asm
11/29/2006 01:11 PM
714 multcode.obj
11/29/2006 01:11 PM
2,597 multcode.lst
11/29/2006 01:11 PM
5,948 multcode.exe
4 File(s)
9,716 bytes
0 Dir(s) 4,028,284,928 bytes free
Press any key to continue . . .
C:\MASM615>multcode
First Message
Second Message
About small model
• When you use model small the assembler automatically
defines DGROUP for near data, accessible via DS or
SS. .DATA and .DATA? Both create near data
segments, placed in DGROUP
• .FARDATA and .FARADATA? Create far data segments
in the small memory model.
• DS (or ES) must point to a sement before a variable in
the segment can be accessed.
• The segment defined by .CODE in the small model is
named _TEXT.
• You can view the naming conventions by examining a lst
file.
Here’s part of the lst for multcode
Segments and Groups:
Name
DGROUP . . . . . . . . . . . . .
_DATA . . . . . . . . . . . . .
STACK . . . . . . . . . . . . .
OtherCode . . . . . . . . . . .
_TEXT . . . . . . . . . . . . .
Size
Length Align Combine Class
GROUP
16 Bit
16 Bit
16 Bit
16 Bit
0021
0100
0008
0014
Word
Para
Word
Word
Public 'DATA'
Stack
'STACK'
Public 'CODE'
Public 'CODE'
Procedures, parameters and locals:
Name
Display . . . . . . . . . . . .
Public STDCALL
WriteString . . . . . . . . . .
main . . . . . . . . . . . . . .
STDCALL
Type
Value
Attr
P Far
0000
OtherCode
Length= 0008
P Near
P Near
0000
0000
Length= 0000 External STDCALL
_TEXT Length= 0014 Public
Modified Multdata from text: multiple data segments
TITLE Multiple Data Segments
(MultData.asm)
; This program shows how to explicitly declare
; multiple data segments.
; Last update: 2/1/02
cseg SEGMENT 'CODE'
ASSUME cs:cseg, ds:data1, ss:mystack
main PROC
mov ax,data1
; point DS to data1 segment
mov ds,ax
mov ax,seg val2
; point ES to data2 segment
mov es,ax
mov ah,2
mov dx,val1
; requires ASSUME for DS
int 21h
mov dx,es:val2
; ASSUME not required
int 21h
mov ax,4C00h
; return to MS-DOS
int 21h
main ENDP
cseg ENDS
data1 SEGMENT 'DATA'
; specify class type
val1 dw 65;;;letter 'A;
data1 ENDS
data2 SEGMENT 'DATA'
val2 dw 57;;;digit char 9
data2 ENDS
mystack SEGMENT para STACK 'STACK'
BYTE 100h dup('S')
mystack ENDS
END main
My version has output (A9)
C:\MASM615>make16 multdata
Assembling: multdata.asm
Volume in drive C has no label.
Volume Serial Number is 07D2-0208
Directory of C:\masm615
11/29/2006 01:31 PM
830 MultData.asm
11/29/2006 01:32 PM
533 multdata.obj
11/29/2006 01:32 PM
1,964 multdata.exe
11/29/2006 01:32 PM
2,297 multdata.lst
4 File(s)
5,624 bytes
0 Dir(s) 4,027,875,328 bytes free
Press any key to continue . . .
C:\MASM615>multdata
A9
Segment overrides
• If you plan to access a value (like [bx] or
[si]) which has a default segment, via a
different segment, you must use an
override.
• Default segment assignments include:
es:di, ds:si, ds:bx, cs:ip, ss:sp
Segment overrides
• You can access a variable without an
assume by using a segment override, that
is, explicitly providing a segment with an
offset.
• This has the form
someseg:someofs
Programs with multiple modules
• One module (B) may define code or data
symbols used in another module (A).
• In order to assemble module A the
assembler needs to know what type the
symbols will have (near, far, byte, word,
dword, etc). An EXTERN directive
assures the assembler the symbols are
defined elsewhere. (It is the programmer’s
responsibility to do this).
Programs with multiple modules
• Module B needs to be assembled so that some
symbols are made available at link time so that
their addresses can be resolved by the linker.
• The PUBLIC directive indicates that a variable
defined in this module may be needed in
another module.
• It is NOT an error if a variable “declared”
PUBLIC is not used elsewhere, but it is an error
if a variable declared “EXTERN” is NOT defined
in another module and declared “PUBLIC” there.
Programs with multiple modules
• Different directives tell the assembler how to combine
segments with the same name.
• COMMON means put them at the same start address
(over each other)
• PUBLIC means combine into a single segment
• PRIVATE is the default, meaning segments with the
same name in different modules will NOT be combined
into a single segment.
• ALIGN tells the assembler on what address boundary to
begin. PARA means paragraph (address ends in 0000).
Higher align types mean faster variable access.
Programs may have multiple
segments which are combined
TITLE Segment Example
(submodule, SEG2A.ASM)
PUBLIC subroutine_1, var2
cseg SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:cseg, ds:dseg
subroutine_1 PROC
; called from MAIN
mov ah,9
mov dx,OFFSET msg
int 21h
ret
subroutine_1 ENDP
cseg ENDS
dseg SEGMENT WORD PUBLIC 'DATA'
var2 WORD 2000h
; accessed by MAIN
msg BYTE 'Now in Subroutine_1'
BYTE 0Dh,0Ah,'$'
dseg ENDS
END
Seg2 from text
TITLE Segment Example
(main module, Seg2.asm)
EXTRN var2:WORD
subroutine_1 PROTO
cseg SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:cseg,ds:dseg, ss:sseg
main PROC
mov ax,dseg
; initialize DS
mov ds,ax
mov ax,var1
; local variable
mov bx,var2
; external variable
call subroutine_1
; external procedure
mov ax,4C00h
; exit to OS
int 21h
main ENDP
cseg ENDS
dseg SEGMENT WORD PUBLIC 'DATA' ; local data segment
var1 WORD 1000h
dseg ends
sseg SEGMENT STACK 'STACK' ; stack segment
BYTE 100h dup('S')
sseg ENDS
END main
Assemble each module separately
C:\MASM615\EXAMPLES\CH16>masm seg2.asm
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c /Ta seg2.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: seg2.asm
MASM : fatal error A1000: cannot open file : seg2.asm
C:\MASM615\EXAMPLES\CH16>cd seg2
C:\MASM615\EXAMPLES\CH16\SEG2>masm seg2
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c seg2.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: seg2.asm
Note how to link (list of modules)
with main first
C:\MASM615\EXAMPLES\CH16\SEG2>link seg2 seg2a
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 199
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Run File [seg2.exe]:
List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
C:\MASM615\EXAMPLES\CH16\SEG2>seg2
Now in Subroutine_1
C:\MASM615\EXAMPLES\CH16\SEG2>
COM and EXE etc
C:\>blah
• Command.COM first checks a command line
instruction to see if it is internal (like DIR).
• After this, it looks for a matching exe file
(blah.exe).
• If this fails, it looks for a com file (blah.com)
• Failing to find one it searches for a batch file.
(blah.bat)
• After this it searches directories in the path for
the program.
Com vs exe
• A com is a binary file. It is loaded by ms-dos at
the lowest available memory location and a PSP
(program segment prefix) is created at offset 0.
Code, data and stack are in the same physical &
logical segment, which may be up to 64K minus
the psp. COM programs use the tiny memory
model.
• All the segment registers are set to the psp
address. The stack area is allocated after the
code and any data.
• You may not explicitly declare a stack segment
Com vs exe
• Com files must start at 100h and so
require code:
Org 100h
• Org instruction tells the assembler what
address to use. Using org, for example,
you can “re-assemble” over previous
assembly by org-ing back to a previous
address.
Hellocom from text
TITLE Hello Program in COM format (HelloCom.asm)
.model tiny
.code
org 100h
; must be before main
main PROC
mov ah,9
mov dx,OFFSET hello_message
int 21h
mov ax,4C00h
int 21h
main ENDP
hello_message BYTE 'Hello, world!',0dh,0ah,'$'
END main
Creating .com instead of .exe
• Link with /t parameter to create a com file.
• there is also a program around named
exe2bin which will convert exe to com
Assembling & running a com file
C:\MASM615>masm hellocom
Microsoft (R) MASM Compatibility Driver
Copyright (C) Microsoft Corp 1993. All rights reserved.
Invoking: ML.EXE /I. /Zm /c hellocom.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: hellocom.asm
C:\MASM615>link /t hellocom
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
Run File [hellocom.com]:
List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
LINK : warning L4045: name of output file is 'hellocom.com'
C:\MASM615>hellocom
Hello, world!
interrupts
• You can customize interrupt handling for
DOS and BIOS by installing you own
handlers
• The hardware was designed with this
possibility of tinkering, or customizing.
• You can replace any service routine with
your own.
Interrupt handlers
• You might want your own program to handle a
special key-press
• A default handler could be replaced by one with
more service. For example, the clock tick
handler which does nothing, could update a
digital or analog clock display on the screen.
• Buffering could be provided for the pc’s
asynchronous communication handler (int 14h)
The vector table: pg 598
• The vector table is in the first K of RAM,
locations 0:0 to 0:03FF
• The entries in the table, called “interrupt
vectors” are 32 bit seg:ofs values that
point to existing service routines.
• The specific values vary from one
computer to another due to different BIOS
or DOS versions
The vector table
• The interrupt vectors correspond to
interrupt numbers
• The address of int 0 handler (div by 0) is
02C1:5186h.
• The offset for a vector can be found by
multiplying the interrupt number by 4 (shl
2)
interrupts
• You can execute an interrupt by
performing an
int XXX
• This is called a software interrupt
• A hardware interrupt may also call the
handler (timer, ports, keyboard and so on
all send signals to the PIC).
interrupts
• A hardware interrupt is generated by the Intel
8259 PIC which signals the cpu to suspend
execution of the current program and execute an
interrupt service handler.
• Note that the current program stack is used to
save the return address.
• The instructions CLI clear interrupt flag (disable)
and STI (enable) set interrupt flag enable a
program to temporarily disable/re-enable
interrupts if sensitive operations are underway,
like changing the value of a segment register.
IRQ
• Interrupts have specific request levels,
given in text table pg 599.
• A low-level interrupt can’t break into a high
level one.
A custom handler: ctrl break
TITLE Control-Break Handler
(Ctrlbrk.asm)
; This program installs its own Ctrl-Break handler and
; prevents the user from using Ctrl-Break (or Ctrl-C)
; to halt the program. The program inputs and echoes
; keystrokes until the Esc key is pressed.
; Last update: 2/1/02
INCLUDE Irvine16.inc
.data
breakMsg BYTE "BREAK",0
msg
BYTE "Ctrl-Break demonstration."
BYTE 0dh,0ah
BYTE "This program disables Ctrl-Break (Ctrl-C). Press any"
BYTE 0dh,0ah
BYTE "keys to continue, or press ESC to end the program."
BYTE 0dh,0ah,0
ctrl break continued
.code
main PROC
mov ax,@data
mov ds,ax
mov dx,OFFSET msg
; display greeting message
call Writestring
install_handler:
push ds
; save DS
mov ax,@code
; initialize DS
mov ds,ax
mov ah,25h
; set interrupt vector
mov al,23h
; for interrupt 23h
mov dx,OFFSET break_handler
int 21h
pop ds
; restore DS
L1:
mov ah,1
int 21h
cmp al,1Bh
jnz L1
; wait for a key, echo it
; ESC pressed?
; no: continue
exit
main ENDP
; The following procedure executes when
; Ctrl-Break (Ctrl-C) is pressed.
break_handler PROC
push ax
push dx
mov dx,OFFSET breakMsg
call Writestring
pop dx
pop ax
iret
break_handler ENDP
END main
Tsr programs
• Terminate-stay-resident
Text example
TITLE Reset-Disabling program
(No_Reset.asm)
; This program disables the usual DOS reset command
; (Ctrl-Alt-Del), by intercepting the INT 9 keyboard
; hardware interrupt. It checks the shift status bits
; in the MS-DOS keyboard flag and changes any Ctrl-Alt-Del
; to Alt-Del. The computer can only be rebooted by
; typing Ctrl+Alt+Right shift+Del. Assemble, link,
; and convert to a COM program by including the /T
; command on the Microsoft LINK command line.
; Last update: 10/12/01
.model tiny
.code
rt_shift EQU 01h
ctrl_key EQU 04h
alt_key EQU 08h
del_key EQU 53h
kybd_port EQU 60h
ORG 100h
start:
jmp setup
; Right shift key: bit 0
; CTRL key: bit 2
; ALT key: bit 3
; scan code for DEL key
; keyboard input port
; this is a COM program
; jump to TSR installation
continued
; Memory-resident code begins here
int9_handler PROC FAR
sti
; enable hardware interrupts
pushf
; save regs & flags
push es
push ax
push di
; Point ES:DI to the DOS keyboard flag byte:
L1: mov ax,40h
; DOS data segment is at 40h
mov es,ax
mov di,17h
; location of keyboard flag
mov ah,es:[di]
; copy keyboard flag into AH
; Test for the CTRL and ALT keys:
L2: test ah,ctrl_key
jz L5
test ah,alt_key
jz L5
; CTRL key held down?
; no: exit
; ALT key held down?
; no: exit
More…
; Test for the DEL and Right-shift keys:
L3: in al,kybd_port
; read keyboard port
cmp al,del_key
; DEL key pressed?
jne L5
; no: exit
test ah,rt_shift
; right shift key pressed?
jnz L5
; yes: allow system reset
L4: and ah,NOT ctrl_key
mov es:[di],ah
; no: turn off bit for CTRL
; store keyboard_flag
L5: pop
pop
pop
popf
jmp
di
ax
es
; restore regs & flags
cs:[old_interrupt9]
; jump to INT 9 routine
old_interrupt9 DWORD ?
int9_handler ENDP
end_ISR label BYTE
And a bit more…
; --------------- (end of TSR program) -----------------; Save a copy of the original INT 9 vector, and set up
; the address of our program as the new vector. Terminate
; this program and leave the int9_handler procedure in memory.
setup:
mov ax,3509h
int 21h
mov word ptr old_interrupt9,bx
mov word ptr old_interrupt9+2,es
mov ax,2509h
mov dx,offset int9_handler
int 21h
; get INT 9 vector
; save INT 9 vector
; set interrupt vector, INT 9
mov ax,3100h
; terminate and stay resident
mov dx,OFFSET end_ISR
; point to end of resident code
shr dx,4
; multiply by 16
inc dx
; round upward to next paragraph
int 21h
; execute MS-DOS function
END start