I am trying to pass 2 variables to a procedure, add them together, and return and print the result. I am using the Stack Frame. I am not getting the right result, rather a large incorrect number. Thank you.
INCLUDE PCMAC.INC
.MODEL SMALL
.586
.STACK 100h
.DATA
sum DWORD ?
.CODE
EXTRN GetDec :NEAR, PutDDec : NEAR, PutHex : NEAR
Main PROC
_Begin
push 10
push 20
call Test12
; Print result
call PutDDec
_Exit
Main ENDP
Test12 PROC
push ebp
mov ebp, esp
mov eax, [ebp+12] ;
add eax, [ebp+8] ;
pop ebp
ret 8
Test12 ENDP
End Main
Your proc looks ok, it does return 30 in eax. However, I can't test it because obviously I don't have the include file PCMAC.INC - is that something for Mac OS, or for Windows? Where did you get it?
This snippet uses the Masm32 library, see installation tips (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm):
include \masm32\include\masm32rt.inc
.code
Test12 PROC
push ebp
mov ebp, esp
mov eax, [ebp+12]
add eax, [ebp+8]
pop ebp
ret 8
Test12 ENDP
start:
push 10
push 20
; int 3 ; for use with Olly (http://www.ollydbg.de/version2.html)
call Test12
MsgBox 0, cat$(str$(eax), " is the sum"), "Masm32 is great:", MB_OK
exit
end start
Btw you might find this thread (http://www.masmforum.com/board/index.php?topic=8888.0) useful. In any case, tell your teacher to install Masm32. The include file pcmac.inc is from the original ML version 6.15, and that is extremely old stuff. Which apparently does not stop people from publishing articles in 2016 (http://jsaer.com/download/vol-3-iss-1-2016/JSAER0301002.pdf) using these macros ::)
Hi,
Here is the PCMAC.INC file:
.XLIST
;; PCMac.inc--Macro INCLUDE file to be used with "Assembly Language
;; for the IBM PC Family" by William B. Jones, (c) Copyright 1992,
;; 1997, 2001, Scott/Jones, Inc.
;; This file has two versions of all the DOS call macros--one beginning '_'
;; which does not save or restore any registers, and one beginning 's'
;; that saves and restores all of the registers ax, bx, cx, and dx which
;; are used by the macro and not used to return a value.
_Begin MACRO
mov ax, @data
mov ds, ax
mov bx, ss
sub bx, ax
shl bx, 4
mov ss, ax
add sp, bx
ENDM
; The following code is necessary to get the .TYPE function to work properly
; in TASM 5. ??VERSION is a built-in variable defined ONLY in TASM
IFDEF ??VERSION
IF ??VERSION GE 500h
OPTION DOTNAME
ENDIF
ENDIF
_LdAddr MACRO reg, addr
IF (.TYPE (addr)) AND 10000B ;; Register
mov reg, addr
ELSE
IF (.TYPE (addr)) AND 100B ;; Constant
mov reg, addr
ELSE
IF TYPE (addr) EQ 1 ;; Bytes
lea reg, addr
ELSE
IF TYPE (addr) EQ 2 ;; Near pointer
mov reg, addr
ELSE
IF TYPE (addr) EQ 4 ;; Far pointer
lds reg, addr
ELSE
.ERR
%OUT Illegal argument
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDM
_LdSeg MACRO reg, segm
IFNB <segm>
IFIDNI <segm>, <es> ;; Segment register
mov ax, segm
mov reg, ax
ELSE
IFIDNI <segm>, <ds>
mov ax, segm
mov reg, ax
ELSE
IFIDNI <segm>, <cs>
mov ax, segm
mov reg, ax
ELSE
IFIDNI <segm>, <ss>
mov ax, segm
mov reg, ax
ELSE
mov ax, segm
mov reg, ax
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDM
_SvRegs MACRO reglist
IRP x, <reglist>
push x
ENDM
ENDM
_RsRegs MACRO reglist
IRP x, <reglist>
pop x
ENDM
ENDM
_PutStr MACRO addr, segm
_LdAddr dx, <addr>
_LdSeg ds, <segm> ;; load segment second in case ax used in addr
mov ah, 09h
int 21h
ENDM
sPutStr MACRO addr, segm
_SvRegs <ax, dx>
_PutStr <addr>, <segm>
_RsRegs <dx, ax>
ENDM
_PutCh MACRO c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
mov ah, 02h
IFB <c1>
int 21h ;; char already in dl
ELSE
IRP x, <c1, c2, c3, c4, c5, c6, c7, c8, c9, c10>
IFB <x>
EXITM
ENDIF
mov dl, x
int 21h
ENDM
ENDIF
ENDM
sPutCh MACRO c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
_SvRegs <ax, dx>
_PutCh c1, c2, c3, c4, c5, c6, c7, c8, c9, c10
_RsRegs <dx, ax>
ENDM
_GetCh MACRO echo
IFIDNI <&echo&>, <noEcho>
mov ah, 08h
ELSE
IFIDNI <&echo&>, <0>
mov al, 08h
ELSE
mov ah, 01h
ENDIF
ENDIF
int 21h
ENDM
sGetCh MACRO echo
_GetCh echo
ENDM
_BIOSCh MACRO
mov ah, 0h
int 16h
ENDM
sBIOSCh MACRO
_BIOSCh
ENDM
_GetStr MACRO Structure, segm
_LdAddr dx, <Structure>
_Ldseg ds, <segm>
mov ah, 0Ah
int 21h
ENDM
sGetStr MACRO Structure, segm
_SvRegs <ax, dx>
_GetStr <Structure>, <segm>
_RsRegs <dx, ax>
ENDM
_GetDate MACRO
mov ah, 2ah
int 21h
ENDM
sGetDate MACRO
_GetDate
ENDM
_GetTime MACRO
mov ah, 2ch
int 21h
ENDM
sGetTime MACRO
_GetTime
ENDM
_Open MACRO filename, accesstype, segm
_LdAddr dx, <filename>
_LdSeg ds, <segm>
mov ah, 3dh
IFB <&accesstype&>
mov al, 0
ELSE
IFIDNI <&accesstype&>, <Read>
mov al, 0
ELSE
IFIDNI <&accesstype&>, <Write>
mov al, 1
ELSE
IFIDNI <&accesstype&>, <ReadWrite>
mov al, 2
ELSE
mov al, accesstype
ENDIF
ENDIF
ENDIF
ENDIF
int 21h
ENDM
sOpen MACRO filename, accesstype, segm
_SvRegs <dx>
_Open <filename>, <accesstype>, <segm>
_RsRegs <dx>
ENDM
_Creat MACRO filename, segm
sub cx, cx
_LdAddr dx, <filename>
_LdSeg ds, <segm>
mov ah, 3ch
int 21h
ENDM
sCreat MACRO filename, segm
_SvRegs <dx>
_Creat <filename>, <segm>
_RsRegs <dx>
ENDM
_Close MACRO handle
mov bx, handle
mov ah, 3eh
int 21h
ENDM
sClose MACRO handle
_SvRegs <bx>
_Close <handle>
_RsRegs <bx>
ENDM
_Read MACRO handle, offs, count, segm
mov cx, count
mov bx, handle
_LdAddr dx, <offs>
_LdSeg ds, <segm>
mov ah, 3fh
int 21h
ENDM
sRead MACRO handle, offs, count, segm
_SvRegs <bx, cx, dx>
_Read <handle>, <offs>, <count>, <segm>
_RsRegs <dx, cx, bx>
ENDM
_Write MACRO handle, offs, count, segm
mov cx, count
mov bx, handle
_LdAddr dx, <offs>
_LdSeg ds, <segm>
mov ah, 40h
int 21h
ENDM
sWrite MACRO handle, offs, count, segm
_SvRegs <bx, cx, dx>
_Write <handle>, <offs>, <count>, <segm>
_RsRegs <dx, cx, bx>
ENDM
_LSeek MACRO Handle, SeekType, LoDistance, HiDistance
IFNB <HiDistance>
mov cx, HiDistance
mov dx, LoDistance
ELSE
IFDIFI <LoDistance>, <ax>
mov ax, LoDistance
ENDIF
cwd
mov cx, dx
mov dx, ax
ENDIF
mov bx, Handle
mov ah, 42h
IFIDNI <SeekType>, <FromStart>
mov al, 0
ELSE
IFIDNI <SeekType>, <FromCur>
mov al, 1
ELSE
IFIDNI <SeekType>, <FromEnd>
mov al, 2
ELSE
mov al, SeekType
ENDIF
ENDIF
ENDIF
int 21h
ENDM
sLSeek MACRO Handle, SeekType, LoDistance, HiDistance
_SvRegs <bx, cx>
_LSeek <Handle>, <SeekType>, <LoDistance>, <HiDistance>
_RsRegs <cx, bx>
ENDM
_Exit MACRO ReturnVal
IFNB <ReturnVal>
mov al, ReturnVal
ENDIF
mov ah, 4ch
int 21h
ENDM
sExit MACRO ReturnVal
_Exit <ReturnVal>
ENDM
_SetIntVec MACRO intr, Handler
push ds
IF TYPE(Handler) EQ 4
lds dx, Handler ; Handler is DWORD PTR to routine
ELSE
IF TYPE(Handler) EQ 0FFFEh ; FAR label
mov ax, SEG Handler
ELSE
mov ax, cs
ENDIF
mov ds, ax
mov dx, OFFSET Handler
ENDIF
mov ah, 25h
mov al, intr
int 21h
pop ds
ENDM
sSetIntVec MACRO intr, Handler
_SvRegs <dx>
_SetIntVec <intr>, <Handler>
_RsRegs <dx>
ENDM
_SaveIntVec MACRO intr, OldIntVec
mov ah, 35h
mov al, intr
int 21h
ASSUME es:NOTHING
mov WORD PTR OldIntVec, bx
mov WORD PTR OldIntVec+2, es
ENDM
sSaveIntVec MACRO intr, OldIntVec
_SvRegs <bx>
_SaveIntVec <intr>, <OldIntVec>
_RsRegs <bx>
ENDM
??? MACRO n ; Placeholder for debugging
mov al, al
ENDM
.LIST
Well, as I wrote above, this is extremely old stuff - copyright 1992 8)
On practically all notebooks that you can buy today, you have a 64-bit version of Windows, and pcmac.inc is 16-bit code that won't run any more. Do you have a really good reason to use 16-bit code?
Hi,
We are using PCMAC in my class, so I kind of have to. Do you know how to do this with 16bit PCMAC? Thanks again so much for your help!
Here is what I get. There must be a *.lib file somewhere that contains the three unresolved externals...
*** Assemble 16-bit app using ml /c /omf /Fo "pcm_test" ***
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: tmp_file.asm
*** Link using link16 ***
Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.
pcm_test.obj(tmp_file.asm) : error L2029: 'PutHex' : unresolved external
pcm_test.obj(tmp_file.asm) : error L2029: 'PutDDec' : unresolved external
pcm_test.obj(tmp_file.asm) : error L2029: 'GetDec' : unresolved external
There were 3 errors detected
*** Link error ***
Attached what I collected so far. I runs fine in my VM, and the result is 30 indeed. The problem is in the "else" part ;-)
Hi,
Yes, my bad. It is using util.lib. I have the lib attached. So to compile you would do "ml Practice.asm util.lib"
To me you're not passing ByRef (Address), but ByVal (Value)
With ByRef you would
mov eax, [ebp+12]
mov eax, [eax]
but at the moment you're pushing values of 10 and 20 onto the stack and not the addresses (ByRef) of these variables.
push 10
push 20
.. instead of
.data
Ten DD 10
Twenty DD 20
.code
.
.
LEA eax, Ten
Push eax
LEA eax, Twenty
Push eax
Just thinking along these lines !!
See attachment to reply #5. The *.asc source opens in RichMasm, WordPad or MS Word.
Quote*** Assemble 16-bit app using ml /c /omf /Fo "pcm_test" ***
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: tmp_file.asm
*** Link using link16 ***
Quote from: jj2007 on May 05, 2016, 04:44:17 AM
See attachment to reply #5. The *.asc source opens in RichMasm, WordPad or MS Word.
Quote*** Assemble 16-bit app using ml /c /omf /Fo "pcm_test" ***
Microsoft (R) Macro Assembler Version 6.15.8803
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.
Assembling: tmp_file.asm
*** Link using link16 ***
You're the man! Works, thank you! :biggrin: :biggrin: :biggrin: