我写了一个简单的程序,它获取一个数组长度,通过使用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_input_format
call scanf
add esp,8
mov eax, [input_value]
push eax
dec edi
jnz array_input
mov edi,[input_length]
sub esp,4
print_array:
mov edx,[esp+4*edi]
push edx
push offset str_format_print
call printf
add esp,8
dec edi
jnz print_array
add esp,4
pop ebp
invoke ExitProcess,0
main ENDP
end
正如您在“print_array”部分之前所看到的,我需要将esp减去4,因为否则我会将当前返回地址打印为数组的第一个元素(因为它将是“esp+20”,而数组从“esp+16”开始)而不是打印的最后一个元素。在部分之后,我向esp添加4以使其再次到达正确的位置。这是打印数组的正确方法吗?还是有另一种方法代替了代码部分之前/之后的sub/add esp by 4?
我知道我需要声明一个变量,但是这个变量应该有动态的长度,因为数组的长度是动态的,所以我不知道如何得到这个变量:/
1条答案
按热度按时间0lvr5msh1#
正如您在“print_array”部分之前所看到的,我需要将esp减去4,因为否则我会将当前返回地址打印为数组的第一个元素(因为它将是“esp+20”,而数组从“esp+16”开始),而不是打印的最后一个元素。
你的偏移量告诉我你为数组输入了5个数字。你的堆栈看起来会像这样:
如果没有
sub esp, 4
,您将检索EBP的保留值,而不是您所说的当前返回地址。在这部分之后,我给esp加上4,让它再次回到正确的位置。这是打印数组的正确方法吗?还是有另一种方法代替了在代码部分之前/之后加上4的sub/add esp?
这里没有错,但是你可以不用
sub
/add
来解决这个问题如果我想把数组保存在堆上,我该怎么做?
如果你需要去那条路,然后阅读有关它在Dynamic Heap Memory in x86 Assembly MASM。
下面的代码版本在一个操作中为堆栈上的数组分配所需的空间,并按正常顺序存储数组元素(这更容易使用)。
第一个