我想知道是否可以重新定义数组的大小,或者只是通过代码段创建一个新的数组。这是我到目前为止所做的:
.DATA
prompt1 db "Please enter a number which will ressemble the N of the array",13,10,'$'
value db ?
.CODE
DisplayIO proc
lea DX, prompt1
mov AH, 09h
int 21h
mov AH, 08h
int 21h
ret
DisplayIO endP
call DisplayIO
sub AL, 30h
mov value, AH
我正在尝试做的,基本上是创建一个大小为value
答案 0 :(得分:1)
在DOS中,您可以使用系统调用(int 21h, ah = 0x48)来保留所选大小的片段(所有片段都是16字节的倍数)。还记得free the block使用int 21h,ah = 0x49。
INT 21,48 - 分配内存
AH = 48h
BX =请求的内存段落数
on return:
AX = segment address of allocated memory block (MCB + 1para)
= error code if CF set (see DOS ERROR CODES)
BX = size in paras of the largest block of memory available
if CF set, and AX = 08 (Not Enough Mem)
CF = 0 if successful
= 1 if error
- returns segment address of allocated memory block AX:0000
- each allocation requires a 16 byte overhead for the MCB
- returns maximum block size available if error
或者您可以从代码/数据静态分配最大长度缓冲区并构建自己的malloc。
答案 1 :(得分:0)
正如 Aki Suihkonen 所说,分配内存是解决方案。我用EMU8086开发了下一个示例:它向用户询问一个数字(数组大小,以字节为单位),然后创建一个该大小的数组。例如,输入20表示20字节的数组,或输入40表示20字的数组。这是代码(有很多评论可以帮助您理解):
.model small
.stack 100h
.data
msg1 db 'Enter the size in byte of the array: $'
size_str db 6,?,6 dup(?) ;ARRAY SIZE IN STRING.
size_num dw ? ;ARRAY SIZE IN NUMERIC.
array_seg dw ? ;ARRAY ON ALLOCATED MEMORY.
;-----------------------------------------------------------------
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;DISPLAY MESSAGE.
mov dx, offset msg1 ;MESSAGE TO DISPLAY.
call printf
;CAPTURE NUMBER AS STRING.
mov dx, offset size_str ;BUFFER TO STORE CAPTURED STRING.
call scanf
;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC.
mov si, offset size_str ;STRING TO CONVERT.
call string2number ;NUMBER RETURNS IN BX.
mov size_num, bx ;PRESERVE RETURNED VALUE.
;ALLOCATE MEMORY FOR THE ARRAY.
call build_array
;EXAMPLE : FILL ARRAY WITH 0.
call zeroes
;WAIT FOR ANY KEY.
mov ah, 7
int 21h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;-----------------------------------------------------------------
;PARAMETER : DX POINTING TO '$' FINISHED STRING.
printf proc
mov ah, 9
int 21h
ret
printf endp
;-----------------------------------------
;PARAMETER : DX POINTING TO BUFFER TO STORE STRING.
scanf proc
mov ah, 0Ah
int 21h
ret
scanf endp
;-----------------------------------------------------------------
;CONVERT STRING TO NUMBER.
;PARAMETER : SI POINTING TO STRING CAPTURED WITH 0AH.
;RETURN : NUMBER IN BX.
string2number proc
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
inc si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx, ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
string2number endp
;-----------------------------------------------------------------
;TO BUILD THE ARRAY IS NECESSARY TO ALLOCATE MEMORY. MEMORY IS
;ALLOCATED IN BLOCKS OF 16 BYTES CALLED "PARAGRAPHS". IT'S NOT
;POSSIBLE TO ALLOCATE ODD NUMBERS, ONLY MULTIPLES OF 16. FOR
;EXAMPLE, FOR AN ARRAY OF 20 BYTES IT'S NECESSARY TO ALLOCATE TWO
;PARAGRAPHS (12 BYTES WASTED).
build_array proc
;FIND OUT HOW MANY PARAGRAPHS WILL BE NEEDED DIVIDING THE
;REQUESTED MEMORY SIZE BY 16.
mov ax, size_num ;REQUESTED MEMORY.
mov bl, 16 ;DIVISOR.
div bl ;AX / 16 : AL=QUOTIENT, AH=REMAINDER.
;IF REMAINDER == 0, SIZE_NUM IS MULTIPLE OF 16, IF REMAINDER != 0,
;ADD ANOTHER PARAGRAPH (SOME BYTES WASTED).
cmp ah, 0
je is_multiple ;IF AH == 0 : JUMP.
;IF NO JUMP, REMAINDER != 0.
inc al ;ANOTHER PARAGRAPH WILL BE NEEDED.
is_multiple:
;ALLOCATE THE MEMORY PARAGRAPHS.
mov bl, al ;NUMBER OF PARAGRAPHS.
mov bh, 0 ;CLEAR BH TO USE BX.
call allocate
ret
build_array endp
;-----------------------------------------------------------------
;ALLOCATES "N" PARAGRAPHS OF MEMORY. ONE PARAGRAPH = 16 BYTES.
;THE RETURNED MEMORY IS A SEGMENT, "ES" CAN BE USED TO POINT TO IT.
;PARAMETER : BX = HOW MANY PARAGRAPHS TO ALLOCATE.
;RETURN : VARIABLE "ARRAY_SEG" WITH ADDRESS OF ALLOCATED SEGMENT.
allocate proc
mov ah, 48h ;SERVICE TO ALLOCATE MEMORY.
int 21h ;RETURNS AX = SEGMENT OF MEMORY ALLOCATED.
mov array_seg, ax
ret
allocate endp
;-----------------------------------------------------------------
;FILL ARRAY WITH ZEROES.
zeroes proc
mov ax, array_seg ;REMEMBER : ARRAY IS A SEGMENT,
mov es, ax ;THAT'S WHY "ES" MUST BE USED.
mov si, 0 ;SI = INDEX FOR THE ARRAY.
mov cx, size_num ;SIZE IN BYTES OF THE ARRAY.
mov dl, 0 ;VALUE TO FILL ARRAY.
filling:
mov [ es:si ], dl ;STORE ZERO IN CURRENT POSITION.
inc si ;MOVE SI TO NEXT POSITION.
loop filling ;CX-1. IF CX > 0 : REPEAT.
ret
zeroes endp
;-----------------------------------------------------------------
end start
一些注意事项:
ES
来访问它的原因。