填充动态分配的内存会冻结程序执行
Filling dynamically allocated memory freezes program execution
我正在使用 TASM 尝试分配一些应该用作缓冲区的内存。
为此,我首先解除分配给可执行文件的所有内存:
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
ADD AX, 0fh
SHR AX, 4
ADD BX, AX
MOV AH, 4ah
INT 21h
之后我尝试使用以下方式分配 64000 字节:
MOV AH, 48h
MOV BX, 64000/16
INT 21h
MOV buffer, AX
这似乎完美无缺,因为执行后未设置 CARRY 标志
指令 21h.
稍后我最终会尝试填充刚刚分配的内存,例如:
MOV BX, OFFSET BUFFER
MOV ES, BX
XOR DI,DI
MOV CX,64000/2
MOV AL,12
MOV AH,AL
REP STOSW
不幸的是失败了,因为程序在 REP STOSW
指令处冻结。
现在我有点迷路了,因为我找不到明显错误的东西。那么为什么会这样呢?
这是我的完整来源:
.MODEL LARGE
.STACK 100h
.DATA?
buffer DW ?
.CODE
Main:
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
ADD AX, 0fh
SHR AX, 4
ADD BX, AX
MOV AH, 4ah
INT 21h
MOV AH, 48h
MOV BX, 64000/16
INT 21h
MOV buffer, AX
MOV BX, OFFSET BUFFER
MOV ES, BX
XOR DI,DI
MOV CX,64000/2
MOV AL,12
MOV AH,AL
REP STOSW
MOV AH,4ch
INT 21h
END Main
MOV BX, OFFSET BUFFER
MOV ES, BX
DOS函数48h给你的信息是一个段落地址。
以上代码将偏移量加载到包含该地址的变量。您需要取消引用它:
MOV ES, buffer
直接来自 AX
:
MOV AH, 48h
MOV BX, 64000/16
INT 21h ; -> AX CF
JC Fail ; Never forget to check for failure
MOV buffer, AX
MOV ES, AX
XOR DI, DI
MOV CX, 64000/2
MOV AX, 0C0Ch
CLD ; Clear direction flag at least once in your program
REP STOSW
Fail:
MOV AX, 4C00h
INT 21h
[编辑]
.MODEL LARGE
.STACK 100h
.DATA?
buffer DW ?
.CODE
通过上面的代码,你的程序内存的高端最终看起来像:
.DATA? .STACK func 48h alloc
... <-- 16 bytes --><-- 256 bytes --><-- 64000 bytes --> ...
94h,08h,0,0,..,0
^ ^ ^
0883h 0884h 0894h <== paragraph addresses
<-- 272 bytes = 17 paragraphs -->
buffer 是 BSS (.DATA?
) 中第一个(也是唯一一个)变量的名称。
mov ax, offset buffer
将 AX
加载为 0,因为 buffer 变量占据了 BSS 中的第一个单词。
mov ax, seg buffer
加载 AX
0883h,即程序加载时分配的 BSS 段落地址。
mov ax, buffer
用 0894h 加载 AX
,buffer 变量的内容,这是 DOS 分配给 64000 字节分配的段落地址。
有关段和段落的更多解释,请阅读:。
我正在使用 TASM 尝试分配一些应该用作缓冲区的内存。
为此,我首先解除分配给可执行文件的所有内存:
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
ADD AX, 0fh
SHR AX, 4
ADD BX, AX
MOV AH, 4ah
INT 21h
之后我尝试使用以下方式分配 64000 字节:
MOV AH, 48h
MOV BX, 64000/16
INT 21h
MOV buffer, AX
这似乎完美无缺,因为执行后未设置 CARRY 标志 指令 21h.
稍后我最终会尝试填充刚刚分配的内存,例如:
MOV BX, OFFSET BUFFER
MOV ES, BX
XOR DI,DI
MOV CX,64000/2
MOV AL,12
MOV AH,AL
REP STOSW
不幸的是失败了,因为程序在 REP STOSW
指令处冻结。
现在我有点迷路了,因为我找不到明显错误的东西。那么为什么会这样呢?
这是我的完整来源:
.MODEL LARGE
.STACK 100h
.DATA?
buffer DW ?
.CODE
Main:
MOV BX, SS
MOV AX, ES
SUB BX, AX
MOV AX, SP
ADD AX, 0fh
SHR AX, 4
ADD BX, AX
MOV AH, 4ah
INT 21h
MOV AH, 48h
MOV BX, 64000/16
INT 21h
MOV buffer, AX
MOV BX, OFFSET BUFFER
MOV ES, BX
XOR DI,DI
MOV CX,64000/2
MOV AL,12
MOV AH,AL
REP STOSW
MOV AH,4ch
INT 21h
END Main
MOV BX, OFFSET BUFFER MOV ES, BX
DOS函数48h给你的信息是一个段落地址。
以上代码将偏移量加载到包含该地址的变量。您需要取消引用它:
MOV ES, buffer
直接来自 AX
:
MOV AH, 48h
MOV BX, 64000/16
INT 21h ; -> AX CF
JC Fail ; Never forget to check for failure
MOV buffer, AX
MOV ES, AX
XOR DI, DI
MOV CX, 64000/2
MOV AX, 0C0Ch
CLD ; Clear direction flag at least once in your program
REP STOSW
Fail:
MOV AX, 4C00h
INT 21h
[编辑]
.MODEL LARGE .STACK 100h .DATA? buffer DW ? .CODE
通过上面的代码,你的程序内存的高端最终看起来像:
.DATA? .STACK func 48h alloc
... <-- 16 bytes --><-- 256 bytes --><-- 64000 bytes --> ...
94h,08h,0,0,..,0
^ ^ ^
0883h 0884h 0894h <== paragraph addresses
<-- 272 bytes = 17 paragraphs -->
buffer 是 BSS (.DATA?
) 中第一个(也是唯一一个)变量的名称。
mov ax, offset buffer
将 AX
加载为 0,因为 buffer 变量占据了 BSS 中的第一个单词。
mov ax, seg buffer
加载 AX
0883h,即程序加载时分配的 BSS 段落地址。
mov ax, buffer
用 0894h 加载 AX
,buffer 变量的内容,这是 DOS 分配给 64000 字节分配的段落地址。
有关段和段落的更多解释,请阅读: