News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Masm Program Help

Started by Omesh, January 13, 2013, 03:17:13 PM

Previous topic - Next topic

Omesh

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


MichaelW

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
Well Microsoft, here's another nice mess you've gotten us into.

dedndave

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

Omesh

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!

dedndave

#4
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

MichaelW

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.
Well Microsoft, here's another nice mess you've gotten us into.


Omesh

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!

dedndave

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