如何处理非固定尺寸阵列?
今天,我正在研究阵列和寻址模式,因此我制作了这个片段来训练自己。一切都很好(显然),但是我选择了使用固定尺寸阵列的最简单方法。我的问题是关于动态内存分配。在我的代码中,我的数组数组
和array2
具有固定的大小(8 * 4(int))。如果我想扩展它们或与C概念交谈,请制作realloc
或类似的内容,取决于大小的实时值,我是否必须实现诸如sys_brk 和
mmap
我自己在汇编中 还是还有其他选择?另一个问题涉及我的代码部分用于逆转数组(标签。reverversing
),我知道它们比我的解决方案更快,因此,如果您能给我一些建议,那就很好。
%define ARRAY_LEN 8
%macro print 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 0x80
%endmacro
%macro exit 0
xor ebx, ebx
mov eax, 1
int 0x80
%endmacro
section .bss
sumarrays resd 1
dynarray resd 256
section .rodata
highest equ 0x78
evensum equ 0x102
sumarray1 equ 0x1e6
sumarray2 equ 0x256
section .data
revarray times ARRAY_LEN dd 0
strok db "Good result !", 0xa, 0
lenstrok equ $ - strok
strerror db "Bad result !", 0xa, 0
lenerror equ $ - strerror
array dd 0x33, 0x21, 0x32, 0x78, 0x48, 0x77, 0x19, 0x10
array2 dd 0x12, 0x98, 0x65, 0x62, 0x4e, 0x3e, 0x1f, 0x3a
section .text
global sort
global sum
global _start
_start:
; sort array from highest value to lowest value
sub esp, 8
push ARRAY_LEN
push array
call sort
add esp, 8
and esp, 0xfffffff0
; copying array into some another ones : array -> revarray
mov esi, eax
mov edi, revarray
mov ecx, ARRAY_LEN
rep movsd
; now let's reverse the array
mov esi, revarray ;esi = address of array
mov ecx, ARRAY_LEN ;ecx = number of elements
lea edi, [esi + ecx * 4 - 4]
.reversing:
mov eax, [esi] ;eax = value at start
mov ebx, [edi] ;ebx = value at end
mov [edi], eax
mov [esi], ebx
add esi, 4 ;incrementing address of next item at start
sub edi, 4 ;incrementing address of next item at end
cmp esi, edi ;middle reached ?
jb .reversing ;no we continue
.reversed:
;after, we compute the sum of the elements in the array
mov esi, revarray ; address of array
mov edx, ARRAY_LEN ; num elem of array
sub esp, 8
call arraysum ; sum computation
add esp, 8
cmp eax, sumarray1 ; we check the result to be sure
jne .failure
; merging array2 with array
; esi = source address of first array
; edi = address of second array, the destination one
mov esi, array2
mov edi, array
sub esp, 8
call mergearrays
add esp, 8
; we compute the sum of the merged arrays into the new (old one in fact)
mov esi, array
mov ecx, ARRAY_LEN
add esp, 8
call arraysum
add esp, 8
cmp eax, 0x43c ; we check the result to be sure
jne .failure ; if not egal, exit
; compute the sum of even numbers only in the array
; set up edx to 0 at beginning of loop
; cmova edx, $value_even_number
mov esi, revarray
xor ebx, ebx
xor ecx, ecx
.iterate:
xor edx, edx ; setting up edx to 0
mov eax, [esi + ecx * 4]
test al, 1 ; CF == 0 ? so it's an even number
cmovz edx, eax ; we store the value of current element in edx
add ebx, edx ; so in case of odd number => add 0
inc ecx
cmp ecx, ARRAY_LEN ; end of array reached ?
jne .iterate ; no, we continue
cmp ebx, 0x102 ; check if result is good
je .success
jmp .failure
exit
.success:
print strok, lenstrok
exit
.failure:
print strerror, lenerror
exit
; ********************************************
; computes the sum of all elements of an array
; esi = address of the array
; edx = number of elements in array
; output : eax
; ********************************************
arraysum:
push ebx
xor ebx, ebx
xor ecx, ecx
.arraysum:
mov eax, [esi + ecx *4]
add ebx, eax
inc ecx
cmp ecx, edx
je .sumdone
jmp .arraysum
.sumdone:
mov eax, ebx
pop ebx
ret
; *********************************************
; procedure that sort array from highest to lowest value
; first arg = address of the array
; second arg = number of elements in a array
; return : eax, sorted array
; ********************************************
sort:
push ebp
mov ebp, esp
mov edx, [ebp + 12]
.loop1:
mov esi, [ebp + 8]
mov ecx, [ebp + 12]
.loop2:
mov eax, [esi]
mov ebx, [esi + 4]
cmp eax, ebx
jg .skip
mov [esi], ebx
mov [esi + 4], eax
.skip:
add esi, 4 ;perform loop checks
dec ecx
cmp ecx, 1
ja .loop2
dec edx
ja .loop1
mov eax,[ebp + 8] ; save result in eax
mov esp,ebp
pop ebp
ret
; ****************************************************
; function adding two arrays merging them
; esi = address of first array
; edi = address of second array (destination array)
; ****************************************************
mergearrays:
xor ecx, ecx
.merging:
mov eax, [esi + ecx * 4]
xadd [edi + ecx * 4], eax
inc ecx
cmp ecx, ARRAY_LEN
je .mergedone
jmp .merging
.mergedone:
ret
Today I'm working on arrays and addressing modes so I made this snippet to train myself. Everything is working fine (apparently) but I chose the easiest way using fixed size arrays. My question is about dynamic memory allocation. In my code, my arrays array
and array2
have a fixed size (8 * 4(int)). If I wanted to extend them, or to speak with C concepts, make a realloc
or something like depending on real time values for the size, may I have to implement system calls like sys_brk
and mmap
by myself in assembly
or is there an other option ? The other question deals with the part of my code used to reverse an array (label .reversing
) I know they are faster solutions than mine so if you could give me some advices, it would be nice.
%define ARRAY_LEN 8
%macro print 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 0x80
%endmacro
%macro exit 0
xor ebx, ebx
mov eax, 1
int 0x80
%endmacro
section .bss
sumarrays resd 1
dynarray resd 256
section .rodata
highest equ 0x78
evensum equ 0x102
sumarray1 equ 0x1e6
sumarray2 equ 0x256
section .data
revarray times ARRAY_LEN dd 0
strok db "Good result !", 0xa, 0
lenstrok equ $ - strok
strerror db "Bad result !", 0xa, 0
lenerror equ $ - strerror
array dd 0x33, 0x21, 0x32, 0x78, 0x48, 0x77, 0x19, 0x10
array2 dd 0x12, 0x98, 0x65, 0x62, 0x4e, 0x3e, 0x1f, 0x3a
section .text
global sort
global sum
global _start
_start:
; sort array from highest value to lowest value
sub esp, 8
push ARRAY_LEN
push array
call sort
add esp, 8
and esp, 0xfffffff0
; copying array into some another ones : array -> revarray
mov esi, eax
mov edi, revarray
mov ecx, ARRAY_LEN
rep movsd
; now let's reverse the array
mov esi, revarray ;esi = address of array
mov ecx, ARRAY_LEN ;ecx = number of elements
lea edi, [esi + ecx * 4 - 4]
.reversing:
mov eax, [esi] ;eax = value at start
mov ebx, [edi] ;ebx = value at end
mov [edi], eax
mov [esi], ebx
add esi, 4 ;incrementing address of next item at start
sub edi, 4 ;incrementing address of next item at end
cmp esi, edi ;middle reached ?
jb .reversing ;no we continue
.reversed:
;after, we compute the sum of the elements in the array
mov esi, revarray ; address of array
mov edx, ARRAY_LEN ; num elem of array
sub esp, 8
call arraysum ; sum computation
add esp, 8
cmp eax, sumarray1 ; we check the result to be sure
jne .failure
; merging array2 with array
; esi = source address of first array
; edi = address of second array, the destination one
mov esi, array2
mov edi, array
sub esp, 8
call mergearrays
add esp, 8
; we compute the sum of the merged arrays into the new (old one in fact)
mov esi, array
mov ecx, ARRAY_LEN
add esp, 8
call arraysum
add esp, 8
cmp eax, 0x43c ; we check the result to be sure
jne .failure ; if not egal, exit
; compute the sum of even numbers only in the array
; set up edx to 0 at beginning of loop
; cmova edx, $value_even_number
mov esi, revarray
xor ebx, ebx
xor ecx, ecx
.iterate:
xor edx, edx ; setting up edx to 0
mov eax, [esi + ecx * 4]
test al, 1 ; CF == 0 ? so it's an even number
cmovz edx, eax ; we store the value of current element in edx
add ebx, edx ; so in case of odd number => add 0
inc ecx
cmp ecx, ARRAY_LEN ; end of array reached ?
jne .iterate ; no, we continue
cmp ebx, 0x102 ; check if result is good
je .success
jmp .failure
exit
.success:
print strok, lenstrok
exit
.failure:
print strerror, lenerror
exit
; ********************************************
; computes the sum of all elements of an array
; esi = address of the array
; edx = number of elements in array
; output : eax
; ********************************************
arraysum:
push ebx
xor ebx, ebx
xor ecx, ecx
.arraysum:
mov eax, [esi + ecx *4]
add ebx, eax
inc ecx
cmp ecx, edx
je .sumdone
jmp .arraysum
.sumdone:
mov eax, ebx
pop ebx
ret
; *********************************************
; procedure that sort array from highest to lowest value
; first arg = address of the array
; second arg = number of elements in a array
; return : eax, sorted array
; ********************************************
sort:
push ebp
mov ebp, esp
mov edx, [ebp + 12]
.loop1:
mov esi, [ebp + 8]
mov ecx, [ebp + 12]
.loop2:
mov eax, [esi]
mov ebx, [esi + 4]
cmp eax, ebx
jg .skip
mov [esi], ebx
mov [esi + 4], eax
.skip:
add esi, 4 ;perform loop checks
dec ecx
cmp ecx, 1
ja .loop2
dec edx
ja .loop1
mov eax,[ebp + 8] ; save result in eax
mov esp,ebp
pop ebp
ret
; ****************************************************
; function adding two arrays merging them
; esi = address of first array
; edi = address of second array (destination array)
; ****************************************************
mergearrays:
xor ecx, ecx
.merging:
mov eax, [esi + ecx * 4]
xadd [edi + ecx * 4], eax
inc ecx
cmp ecx, ARRAY_LEN
je .mergedone
jmp .merging
.mergedone:
ret
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论