Inactive write to stack inside an external procedure
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
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 ?
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.