Search code examples
assemblystackx86-16procedurescode-view

Writing to Stack in Extern 8086 Procedure is inactive through MOV [BP] ,AL


Problem :

Inactive write to stack inside an external procedure

Code :

Inside an extern procedure which asks the user to input a string then returning it to the main through the stack.

String is defined at the data segment with a name different than that of data segment inside main procedure file.

Data_segment_name_ext segment para
ORG 10H
Str  DB 20,?,20 DUP (?)
Data_segment_name_ext ends

and stack segment declaration :

Stack_segment_name segment para stack
db 64 dup(0) ;define your stack segment
Stack_segment_name ends

originally at the procedure beginning I declared it public and set BP to Stack top :

PUBLIC MyProc
Code_segment_name segment
MyProc PROC FAR
assume SS:Stack_segment_name,CS:Code_segment_name,DS:Data_segment_name_ext
PUSH BP 
MOV BP,SP

String is being read by function AH=0x0A interrupt 0x21

LEA DX,Str
MOV AH,0Ah
INT 21H

Trying to save the string into the stack using the following loop :

MOV CX,22 ; The string length
MOV SI,00 ; used as an index
TRA1:
DEC BP
MOV AL,Str[SI] ; Str is defined in the data segment
MOV [BP],AL 
INC SI
LOOP TRA1

debugging the program using code view 4.01 and MASM 6.11 results in the following :

1-String is read correctly and stored in the DS and offset Str [Actual string starts two bytes after max length,actual count]

2-Strange behavior in the writing string into the stack:

Let SP originally=0xBA after the loop BP=0xA4 (i.e 0xBA-0x16(String length)) Dumping Stack Segment at SS:0xA4 Showing a garbage data 8 bytes before SS:SP and correct data is being written beyond this.

if the str='ABCDEFGHIJ' only 'GHIJ' are saved on the stack

>DB SS:0xA4

SS:00A4 00 00 00 00 00 00 00 00   00 00 4A 49 48 47 E7 05  ..........JIHG.. 
SS:00B4 7E 00 FD 05 02 02 00 00   0A 00 0C 06 B8 E7 05 8E  ~...............

Note : 060C:000A was CS:IP before executing the far call to the extern procedure and is pushed successfully @SP=0xC0(i.e. at SS:0xBC,SS:0xBD,SS:0xBE,SS:0xBF)

3-Replacing MOV [BP],AL by MOV [BP],33h results in the same behavior ;33h is not written in the first 8 bytes around old TOS

4-Enforcing SS (i.e. MOV SS:[BP],AL ) is also helpless as same behavior occurs

I know that I could return the parameters in alternative ways but why this behavior happens ?


Solution

  • Since the purpose of your procedure MyProc is to return a string through the stack you inevitably have to store it above the return address pushed on the stack by the call instruction. This code does that:

    sub  sp, 22
    call MyProc
    

    Now instead of inputting via an extra buffer in DS you could simplify the task and input directly in the space that you vacated on the stack.

    mov  ax, 20
    sub  sp, ax
    push ax         ;This sets up the correct buffer DOS expects
    call MyProc
    ...
    MyProc PROC FAR
    assume SS:Stack_segment_name,CS:Code_segment_name
    PUSH BP 
    MOV  BP,SP
    push ds
    push ss
    pop  ds
    lea  dx, [bp+6]
    ;String is being read by function AH=0x0A interrupt 0x21
    MOV AH,0Ah
    INT 21H
    pop  ds
    ...
    

    I see that you've set up a stack of only 64 bytes. If you plan to store strings in the stack I advice you to increase this size.