assembly 汇编MASM以正确的方式将动态数组保存在内存中

oxalkeyp  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(141)

你好,我想在内存中保存一个由用户定义的长度和值的数组。实际上我是在存储插入在“[ebp+8+esi*4]"的值,所以在函数参数之后。这是正确的吗?或者我应该怎么做?我认为局部变量应该放在esp下面的内存地址,所以通过递减esp为局部变量腾出空间。但是我不能动态递减“esp”,那我该怎么办呢?
这是代码:

.686
.xmm
.model flat, C
OPTION CaseMap:None

include ../masm32/libs/windows.inc
include ../masm32/libs/kernel32.inc
include ../masm32/libs/user32.inc
include ../masm32/libs/msvcrt.inc
include ../masm32/libs/masm32.inc

EXTERN printf:PROC
EXTERN scanf:PROC

.data
    str_insert_array_length db  "Insert Array Length: ",0
    str_insert_value    db  10,"Insert Value: ",0
    str_input_format    db  "%d",0
    str_format_print db "%d",10,0

    input_length   DWORD    0
    input_value    DWORD    0

.code

main PROC
    push ebp
    mov ebp,esp

    push offset str_insert_array_length
    call printf
    add esp,4

    push offset input_length
    push offset str_input_format
    call scanf
    add esp,8
    
mov edi,[input_length]

array_input:
    push offset str_insert_value
    call printf
    add esp,4

    push offset input_value
    push offset str_format
    call scanf
    add esp,8

    mov eax, [input_value]
    push eax

    dec edi
    jnz array_input

    mov edi,[input_length]
    xor esi,esi

    push offset str_print_array
    call printf
    add esp,4

print_array:
    mov edx,[esp+4*esi]
    push edx
    push offset str_format_print
    call printf
    add esp,8
    inc esi
    dec edi
    jnz print_array

    pop ebp
    invoke ExitProcess,0
main ENDP
    end
woobm2wo

woobm2wo1#

您可以动态递减sp。只需使用减法指令,如sub esp, eax,其中您已经在eax中建立了动态递减量。如果您这样做,则新数组将从esp中的地址开始。
问题是,在知道输入了多少项之前,您无法计算递减量。
因此,如果在用户要求停止之前,你不知道有多少项,那么你可以在输入时将单个项压入堆栈,但结果数组中的元素将按记忆顺序反向排列--所以,你可以稍后用一个简单的循环将它们反向排列,或者如果程序的其余部分不太复杂的话,选择按反向顺序工作。
这种方式使用堆栈会因为对齐要求而变得更加复杂。首先,x86的对齐大于一个整数,因此在函数调用之前,有时需要在堆栈上填充,例如printf。其次,如果数组的元素大小小于一个整数,例如一个字节或8位字符,则压入会将填充引入到全整数大小。因此堆栈上的项不仅在内存中向后排列,而且还通过填充展开。
由于堆栈的这些复杂性,通常使用其他解决方案:固定大小缓冲区或可扩展数组。
对于固定大小的缓冲区,只需要分配比所需更多的空间即可。因此,为128个元素分配空间(满足对齐)。如果遇到超过此数量的元素,可以简单地停止程序并显示错误消息。
对于可扩展数组,要添加元素,分配更多的存储空间,并将现有的拷贝到更大的新存储空间中。有多种技术可以减少拷贝数,作为速度和空间的折衷。这种方法通常使用堆内存而不是堆栈。

相关问题