layout | title | permalink |
---|---|---|
page |
Q70671: Return Must Match Memory Model for CALL to Label in Proc |
/kb/070/Q70671/ |
{% raw %}
Article: Q70671
Product(s): Microsoft Macro Assembler
Version(s): 5.1,5.1a,6.0,6.0a,6.0b
Operating System(s):
Keyword(s):
Last Modified: 06-MAY-2001
-------------------------------------------------------------------------------
The information in this article applies to:
- Microsoft Macro Assembler (MASM), versions 5.1, 5.1a, 6.0, 6.0a, 6.0b
-------------------------------------------------------------------------------
SUMMARY
=======
With the Macro Assembler (MASM), if a CALL is made to a label within a
procedure, a near call is generated by default. Depending on the memory model
being used, you may need to explicitly specify the correct return.
MORE INFORMATION
================
The standard RET instruction pops off the return address depending on the memory
model. In a small memory model program, the RET instruction is converted to a
RETN, which only pops off the offset to return. In medium and large memory
models, the RET is converted to RETF, which pops off both the segment and offset
to return from the far call. Because a call to a label within a procedure always
results in a near call, the RETF instruction that is generated in medium and
large models will pop a segment value for the return address that was never
pushed.
To ensure that the right size address is popped off the stack relative to that
pushed on the stack, one of the following methods may be used:
1. Use the RET return, but push CS before the call so that the segment and
offset will both be on the stack for the far return:
PUSH CS
CALL label1
- or -
2. Use the FAR PTR override on the call along with a RET to return, so that both
segment and offset are pushed and popped off the stack:
CALL FAR PTR label1
- or -
3. Use the LABEL FAR directive along with a RET return so that the assembler
will generate a far return to match the far label call:
label1 LABEL FAR
- or -
4. If the label is called ONLY from within the procedure, use RETN explicitly
(instead of RET) to indicate the NEAR return, so that only the offset is
popped off the stack:
label1:
RETN
The sample code below demonstrates the need for the proper return for a call to a
label. When assembled and run as is, the code will hang the computer. Adding any
of the solutions described above will correct the code. Comments are included at
the locations where each correction should go.
Sample Code
-----------
; Assemble options needed : none
.MODEL large
.STACK
.CODE
start: call proc1
mov ah, 4ch
mov al, 0
int 21h
proc1 PROC
; #1 - add PUSH CS instruction here
CALL label1 ; #2 - change call to CALL FAR PTR label1
RET
label1: ; #3 - change label to label1 LABEL FAR
RET ; #4 - change return to RETN
proc1 ENDP
END start
Additional query words: kbinf 5.10 6.00 6.00a 6.00b
======================================================================
Keywords :
Technology : kbMASMsearch kbAudDeveloper kbMASM510 kbMASM600 kbMASM600a kbMASM510a kbMASM600b
Version : :5.1,5.1a,6.0,6.0a,6.0b
=============================================================================
{% endraw %}