Hello I am a beginner working on a masm program.
my task is to write a program to add the following 4 numbers
Week1=35,Week30,Week3=40,Week4=35
and store the sum in Total
This is what I came up with :
TITLE PGM1
;*******************************************************
; PRG1 TITLE SAMPLE TO ADD COST TO TOTAL *
; PROGRAMMER: *
; PURPOSE:ADDING 4 NUMBERS *
; *
; *
;*******************************************************
PGM1CD SEGMENT
MAIN PROC FAR
;HOUSEKEEPING SECTION
ASSUME CS:PGM1CD,DS:PGM1DA,SS:PGM1SK
MOV AX,PGM1DA ;ESTABLISH ADDRESSABILITY
MOV DS,AX ;TO PGM1DA - The PGN'S DATA SEGMENT
; MAIN PROCESS SECTION
MOV AX, WEEK1 ; REG AX = ACCUMULATE
ADD AX, WEEK2 ; REG AX = ACCUMULATE
ADD AX, WEEK3 ; REG AX = ACCUMULATE
ADD AX, WEEK4 ; REG AX = ACCUMULATE
ADD AX, TOTAL ; ADD ACCUMULATE TO TOTAL
MOv TOTAL,AX ;STORE NEW TOTAL
; RETURN TO DOS SECTION
MOV AL,0 ;SET 0 AS THE RETURN CODE FOR DOS
MOV AH,4CH ;SET FOR DOS END PROCESS FUNCTION
INT 21H ;CALL DOS TO END PROGRAM
MAIN ENDP
PGM1CD ENDS
; PROGRAM DATA SEGMENT
PGM1DA SEGMENT
WEEK1 DW 35
WEEK2 DW 30
WEEK3 DW 40
WEEK4 DW 35
TOTAL DW 0
ACCUMLATE 0
PGM1DA ENDS
; PROGRAM STACK SEGMENT
PGM1SK SEGMENT PARA STACK 'STACK'
DW 32 DUP (?)
PGM1SK ENDS
END
Trying to assemble your code the assembler returned:
omesh.asm(49) : error A2008: syntax error : ACCUMLATE
After fixing the error, the linker returned:
LINK : warning L4038: program has no starting address
To specify a starting address:
PGM1SK ENDS
END MAIN
Running the code in DEBUG it stores the correct value in TOTAL, but:
ADD AX, TOTAL ; ADD ACCUMULATE TO TOTAL
Serves no purpose because it is actually adding TOTAL, which has a value of zero, to AX and storing the result in AX.
IOW: AX = AX + TOTAL
hi Omesh - welcome to the forum
i noticed a few other oddities in your program, in addition to the ones Michael mentioned
one was that 32 words of stack space is very small :P
it may be ok under win32, but would almost certainly crash if running under DOS
Michael mentioned that adding TOTAL to the accumulator served no purpose
but, noticing the title of the program, i can see where it would be ok to do that
TOTAL may have a predefined non-zero value
however, you could do it by adding the 4 week values together in a register
then, adding that register to TOTAL
also, you can use simplified directives to open and close segments
.MODEL Small
.386
.STACK 1024
OPTION CaseMap:None
;####################################################################################
.DATA
WEEK1 DW 35
WEEK2 DW 30
WEEK3 DW 40
WEEK4 DW 35
TOTAL DW 0
;************************************************************************************
; .DATA?
;####################################################################################
.CODE
;************************************************************************************
_main PROC FAR
;----------------------------------
; DS = DGROUP
mov ax,@data
mov ds,ax
;----------------------------------
; MAIN PROCESS SECTION
MOV AX, WEEK1 ; REG AX = ACCUMULATE
ADD AX, WEEK2 ; REG AX = ACCUMULATE
ADD AX, WEEK3 ; REG AX = ACCUMULATE
ADD AX, WEEK4 ; REG AX = ACCUMULATE
ADD TOTAL, AX ; ADD ACCUMULATE TO TOTAL
; RETURN TO DOS SECTION
MOV AL, 0 ; SET 0 AS THE RETURN CODE FOR DOS
MOV AH, 4CH ; SET FOR DOS END PROCESS FUNCTION
INT 21H ; CALL DOS TO END PROGRAM
_main ENDP
;####################################################################################
END _main
C:\Masm32\Asm16 => SymDeb Omesh.exe
Microsoft (R) Symbolic Debug Utility Version 4.00
Copyright (C) Microsoft Corp 1984, 1985. All rights reserved.
Processor is [80286]
-u
0F5A:0000 B85B0F MOV AX,0F5B
0F5A:0003 8ED8 MOV DS,AX
0F5A:0005 A10E00 MOV AX,[000E]
0F5A:0008 03061000 ADD AX,[0010]
0F5A:000C 03061200 ADD AX,[0012]
0F5A:0010 03061400 ADD AX,[0014]
0F5A:0014 01061600 ADD [0016],AX
0F5A:0018 B000 MOV AL,00
0F5A:001A B44C MOV AH,4C ;'L'
0F5A:001C CD21 INT 21
-r
AX=0000 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F4A ES=0F4A SS=0F5D CS=0F5A IP=0000 NV UP EI PL NZ NA PO NC
0F5A:0000 B85B0F MOV AX,0F5B
-t
AX=0F5B BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F4A ES=0F4A SS=0F5D CS=0F5A IP=0003 NV UP EI PL NZ NA PO NC
0F5A:0003 8ED8 MOV DS,AX
-t
AX=0F5B BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0005 NV UP EI PL NZ NA PO NC
0F5A:0005 A10E00 MOV AX,[000E] DS:000E=0023
-t
AX=0023 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0008 NV UP EI PL NZ NA PO NC
0F5A:0008 03061000 ADD AX,[0010] DS:0010=001E
-t
AX=0041 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=000C NV UP EI PL NZ AC PE NC
0F5A:000C 03061200 ADD AX,[0012] DS:0012=0028
-t
AX=0069 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0010 NV UP EI PL NZ NA PE NC
0F5A:0010 03061400 ADD AX,[0014] DS:0014=0023
-t
AX=008C BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0014 NV UP EI PL NZ NA PO NC
0F5A:0014 01061600 ADD [0016],AX DS:0016=0000
-t
AX=008C BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0018 NV UP EI PL NZ NA PO NC
0F5A:0018 B000 MOV AL,00
-t
AX=0000 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=001A NV UP EI PL NZ NA PO NC
0F5A:001A B44C MOV AH,4C ;'L'
-t
AX=4C00 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=001C NV UP EI PL NZ NA PO NC
0F5A:001C CD21 INT 21 ;Terminate a Process
Well thanks for the quick response guys!
I was going off my professor's sample + the textbook (although its horribly written)
I have a few questions for dedndave or anyone able to answer.
.MODEL Small
.386
.STACK 1024
OPTION CaseMap:None
What exactly is this part for is it just something that needs to be there to start the processes?
;************************************************************************************
; .DATA?
;####################################################################################
.CODE
;************************************************************************************
_main PROC FAR
;----------------------------------
Confused about this section also . How exactly does "_main PROC FAR" do and is .DATA and .CODE necessary.
Keep in mind I'm a beginner and these particular parts are new to me.
Thx again for the speedy replys you guys are a great community!
the .MODEL directive tells the assembler what 16-bit memory model to use
16-bit code on an 80x86 processor uses segmented memory
the memory model can be tiny, small, medium, compact, large, huge
tiny model - all code, data, and stack space fits into one 64 kb segment
small model - all code is in one 64 kb segment, all data is in one 64 kb segment, stack is in one 64 kb segment
the other models have multiple code segments, multiple data segments, or both
huge was rarely used, where a data segment must be contiguous across more than 64 kb
when i say "64 kb segment", i am refering to the maximum size
for 16-bit intel CPU's, memory was addressed by using a segment register and an offset
the segment registers for 80x86 processors are CS, DS, ES, SS
code, data, extra data, stack
each segment register points to the base of a 64 kb segment of memory
a physical address on older CPU's was calculated as
16 x segment + offset
only 64 kb may be addressed at a time, using one segment register value
this is because the offset is only 16 bits wide
but, by using segment registers, you can address 1 mb of memory
newer processors are able to work this way for backward compatibility
.386 - tells the assembler which instruction set to allow
the default is .8086
nowdays, we use .586 or .686, mostly, for 32-bit programs
but, for 16-bit code, .386 allows the use of older 32 bit instructions
.STACK 1024 - creates a stack segment with 1024 bytes of stack space
the assembler uses default names and attributes for segments created this way
OPTION CaseMap:None - means that label names are case sensitive
after that, you can use .DATA, .DATA?, and .CODE to open segments with little typing
again, the assembler uses default names and attributes for segments created this way
in the old days, we used to create segments something like this
_TEXT SEGMENT WORD PUBLIC 'CODE'
_TEXT ENDS
but, most of us use the simplified directives, now
segments cannot be nested, so when you open one segment, it closes any previously opened segment
FAR and NEAR procedures differ in the type of RET instruction that is used
this tells the assembler whether to use RETN or RETF when it sees RET in the source code
it also tells the assembler whether to use a FAR call or a NEAR call when calling the procedure
for NEAR calls, only the instruction pointer is pushed onto the stack
so, when you RETurn, only the IP is popped off with RETN
for FAR calls, the code segment is pushed, then the instruction pointer
this allows for calls into different code segments
by nature, 16-bit EXE's use a far procedure for the main entry point
16-bit tiny model programs would use a near procedure for the main entry point
procedures other than the main entry may be near or far, depending on the segment
quite often, they can be near because the procedure is in the same segment as the call
if you google around, you will find the masm programmers reference guide
it's a lot of reading - most of which may not mean anything until you get your feet wet
but, all this stuff is explained in that manual
Omesh,
If you assemble Dave's code with this batch file:
:
: This batch file assumes that ML.EXE, ML.ERR, and
: Link16.exe are in the current directory and that
: the assembly code source is named sample.asm.
:
set file="sample"
if exist %file%.obj del %file%.obj
if exist %file%.exe del %file%.exe
ml /W3 /Fl /Sa /c %file%.asm
pause
Link16 /MAP %file%.obj;
Pause
Then ML will generate this listing:
Microsoft (R) Macro Assembler Version 6.15.8803 01/13/13 12:32:59
sample.asm Page 1 - 1
.MODEL Small
.386
.STACK 1024
OPTION CaseMap:None
;####################################################################################
0000 .DATA
0000 0023 WEEK1 DW 35
0002 001E WEEK2 DW 30
0004 0028 WEEK3 DW 40
0006 0023 WEEK4 DW 35
0008 0000 TOTAL DW 0
;************************************************************************************
; .DATA?
;####################################################################################
0000 .CODE
;************************************************************************************
0000 _main PROC FAR
;----------------------------------
; DS = DGROUP
0000 B8 ---- R mov ax,@data
0003 8E D8 mov ds,ax
;----------------------------------
; MAIN PROCESS SECTION
0005 A1 0000 R MOV AX, WEEK1 ; REG AX = ACCUMULATE
0008 03 06 0002 R ADD AX, WEEK2 ; REG AX = ACCUMULATE
000C 03 06 0004 R ADD AX, WEEK3 ; REG AX = ACCUMULATE
0010 03 06 0006 R ADD AX, WEEK4 ; REG AX = ACCUMULATE
0014 01 06 0008 R ADD TOTAL, AX ; ADD ACCUMULATE TO TOTAL
; RETURN TO DOS SECTION
0018 B0 00 MOV AL, 0 ; SET 0 AS THE RETURN CODE FOR DOS
001A B4 4C MOV AH, 4CH ; SET FOR DOS END PROCESS FUNCTION
001C CD 21 INT 21H ; CALL DOS TO END PROGRAM
001E _main ENDP
;####################################################################################
END _main
Microsoft (R) Macro Assembler Version 6.15.8803 01/13/13 12:32:59
sample.asm Symbols 2 - 1
Segments and Groups:
N a m e Size Length Align Combine Class
DGROUP . . . . . . . . . . . . . GROUP
_DATA . . . . . . . . . . . . . 16 Bit 000A Word Public 'DATA'
STACK . . . . . . . . . . . . . 16 Bit 0400 Para Stack 'STACK'
_TEXT . . . . . . . . . . . . . 16 Bit 001E Word Public 'CODE'
Procedures, parameters and locals:
N a m e Type Value Attr
_main . . . . . . . . . . . . . P Far 0000 _TEXT Length= 001E Public
Symbols:
N a m e Type Value Attr
@CodeSize . . . . . . . . . . . Number 0000h
@DataSize . . . . . . . . . . . Number 0000h
@Interface . . . . . . . . . . . Number 0000h
@Model . . . . . . . . . . . . . Number 0002h
@code . . . . . . . . . . . . . Text _TEXT
@data . . . . . . . . . . . . . Text DGROUP
@fardata? . . . . . . . . . . . Text FAR_BSS
@fardata . . . . . . . . . . . . Text FAR_DATA
@stack . . . . . . . . . . . . . Text DGROUP
TOTAL . . . . . . . . . . . . . Word 0008 _DATA
WEEK1 . . . . . . . . . . . . . Word 0000 _DATA
WEEK2 . . . . . . . . . . . . . Word 0002 _DATA
WEEK3 . . . . . . . . . . . . . Word 0004 _DATA
WEEK4 . . . . . . . . . . . . . Word 0006 _DATA
0 Warnings
0 Errors
And Link16 will generate this map file:
Start Stop Length Name Class
00000H 0001DH 0001EH _TEXT CODE
0001EH 00027H 0000AH _DATA DATA
00030H 0042FH 00400H STACK STACK
Origin Group
0001:0 DGROUP
Address Publics by Name
0000:0000 _main
Address Publics by Value
0000:0000 _main
Program entry point at 0000:0000
Hopefully the listing and map file will help answer some of your questions.
I suspect that your professor expects you to start with the basics, and this means full segment definitions.
this may be helpful...
http://msdn.microsoft.com/en-US/library/d06y3478%28v=vs.80%29.aspx (http://msdn.microsoft.com/en-US/library/d06y3478%28v=vs.80%29.aspx)
Yes we started our with full segment definitions. Since its a 6 weeks class, I'm also self learning!
Thanks again for the push in the right direction its a lot of reading but at least now I know what to research.
I'll probably be lurking around this forums for practical help =]
huge thanks to Dave and Mike you weren't obligated to spend so much time helping me :] but i appreciate it dearly!
one of the other directives (that i had forgotten) is .DOSSEG
it orders the segments as they were needed for DOS debuggers of old
however, because you will be defining the segments, yourself,
you can determine how the segments are ordered,
which will be the same order they appear in the source file
;####################################################################################
_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:_TEXT, DS:_DATA, SS:STACK
;************************************************************************************
_main PROC FAR
;----------------------------------
; DS = _DATA SEGMENT
MOV AX, _DATA
MOV DS, AX
;----------------------------------
; MAIN PROCESS SECTION
MOV AX, WEEK1 ; REG AX = ACCUMULATE
ADD AX, WEEK2 ; REG AX = ACCUMULATE
ADD AX, WEEK3 ; REG AX = ACCUMULATE
ADD AX, WEEK4 ; REG AX = ACCUMULATE
ADD TOTAL, AX ; ADD ACCUMULATE TO TOTAL
;----------------------------------
; RETURN TO DOS SECTION
MOV AL, 0 ; SET 0 AS THE RETURN CODE FOR DOS
MOV AH, 4CH ; SET FOR DOS END PROCESS FUNCTION
INT 21H ; CALL DOS TO END PROGRAM
;----------------------------------
_main ENDP
;************************************************************************************
_TEXT ENDS
;####################################################################################
_DATA SEGMENT WORD PUBLIC 'DATA'
WEEK1 DW 35
WEEK2 DW 30
WEEK3 DW 40
WEEK4 DW 35
TOTAL DW 0
_DATA ENDS
;####################################################################################
STACK SEGMENT PARA STACK 'STACK'
DW 512 DUP(?)
STACK ENDS
;####################################################################################
END _main
C:\Masm32\Asm16 => SymDeb Omesh2.exe
Microsoft (R) Symbolic Debug Utility Version 4.00
Copyright (C) Microsoft Corp 1984, 1985. All rights reserved.
Processor is [80286]
-u 0 1d
0F5A:0000 B85B0F MOV AX,0F5B
0F5A:0003 8ED8 MOV DS,AX
0F5A:0005 A10E00 MOV AX,[000E]
0F5A:0008 03061000 ADD AX,[0010]
0F5A:000C 03061200 ADD AX,[0012]
0F5A:0010 03061400 ADD AX,[0014]
0F5A:0014 01061600 ADD [0016],AX
0F5A:0018 B000 MOV AL,00
0F5A:001A B44C MOV AH,4C ;'L'
0F5A:001C CD21 INT 21
-dw f5b:e 17
0F5B:000E 0023 001E 0028 0023 0000
-r
AX=0000 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F4A ES=0F4A SS=0F5D CS=0F5A IP=0000 NV UP EI PL NZ NA PO NC
0F5A:0000 B85B0F MOV AX,0F5B
-t
AX=0F5B BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F4A ES=0F4A SS=0F5D CS=0F5A IP=0003 NV UP EI PL NZ NA PO NC
0F5A:0003 8ED8 MOV DS,AX
-t
AX=0F5B BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0005 NV UP EI PL NZ NA PO NC
0F5A:0005 A10E00 MOV AX,[000E] DS:000E=0023
-t
AX=0023 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0008 NV UP EI PL NZ NA PO NC
0F5A:0008 03061000 ADD AX,[0010] DS:0010=001E
-t
AX=0041 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=000C NV UP EI PL NZ AC PE NC
0F5A:000C 03061200 ADD AX,[0012] DS:0012=0028
-t
AX=0069 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0010 NV UP EI PL NZ NA PE NC
0F5A:0010 03061400 ADD AX,[0014] DS:0014=0023
-t
AX=008C BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0014 NV UP EI PL NZ NA PO NC
0F5A:0014 01061600 ADD [0016],AX DS:0016=0000
-t
AX=008C BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=0018 NV UP EI PL NZ NA PO NC
0F5A:0018 B000 MOV AL,00
-t
AX=0000 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=001A NV UP EI PL NZ NA PO NC
0F5A:001A B44C MOV AH,4C ;'L'
-t
AX=4C00 BX=0000 CX=0028 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=0F5B ES=0F4A SS=0F5D CS=0F5A IP=001C NV UP EI PL NZ NA PO NC
0F5A:001C CD21 INT 21 ;Terminate a Process
-dw ds:e 17
0F5B:000E 0023 001E 0028 0023 008C
-q