问题 :
在外部过程中对堆栈进行非活动写入
代码 :
在一个外部过程中,它要求用户输入一个字符串,然后通过堆栈将其返回给主程序。
字符串在数据段中定义,其名称与主过程文件中的数据段不同。
Data_segment_name_ext segment para
ORG 10H
Str DB 20,?,20 DUP (?)
Data_segment_name_ext ends
和堆栈段声明:
Stack_segment_name segment para stack
db 64 dup(0) ;define your stack segment
Stack_segment_name ends
最初在程序开始时,我将其声明为 public 并将 BP 设置为 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
函数正在读取字符串 AH=0x0A 中断 0x21
LEA DX,Str
MOV AH,0Ah
INT 21H
尝试使用以下循环将字符串保存到堆栈中:
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
使用代码视图 4.01 和 MASM 6.11调试程序会产生以下结果:
1-String 被正确读取并存储在 DS 和偏移量 Str [Actual string 在最大长度后开始两个字节,实际计数]
2-将字符串写入堆栈的奇怪行为:
让 SP 在循环之后最初 = 0xBA BP=0xA4(即 0xBA-0x16(字符串长度)) 在 SS:0xA4 处转储堆栈段 在 SS:SP 之前的 8 个字节处显示垃圾数据,并且在此之后写入正确的数据。
如果 str='ABCDEFGHIJ' 只有 'GHIJ' 保存在堆栈中
>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 ~...............
注意:060C:000A 在执行对 extern 过程的远调用之前是 CS:IP,并且被成功推送@SP=0xC0(即在 SS:0xBC,SS:0xBD,SS:0xBE,SS:0xBF)
3-将 MOV [BP],AL 替换为 MOV [BP],33h 会导致相同的行为;33h 未写入旧 TOS 周围的前 8 个字节
4-强制执行 SS(即 MOV SS:[BP],AL )也无能为力,因为发生了相同的行为
我知道我可以以其他方式返回参数,但为什么会发生这种行为?