728x90
이 글은 단순하게 list 에대해 공부 중 extend 와 + 를 활용하여 list를 확장 할때
어떤식으로 메모리가 변화가 있는지 에 대해 너무나 궁금해져서 공부 하게 되었다.
이와 관련하여 정리 하고자 하는 글입니다.
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [11, 12, 13, 14, 15]
def one():
return a + b
def two():
return a.extend(b)
두개의 리스트가 존재 하고 두개 의 함수가 존재 한다고 했을때
어셈블리어는 아래와 같이 존재 한다.
section .data
a db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
a_len equ 10
b db 11, 12, 13, 14, 15
b_len equ 5
section .text
global _start
_start:
; Call one()
call one
; Print the result of one()
mov ecx, eax
mov edx, a_len + b_len
call print_array
; Call two()
call two
; Print the result of two()
mov ecx, a
mov edx, a_len + b_len
call print_array
; Exit the program
mov eax, 1
xor ebx, ebx
int 0x80
; Concatenates arrays a and b and returns the resulting array
one:
push ebp
mov ebp, esp
; Calculate the length of the resulting array
mov ecx, a_len
add ecx, b_len
; Allocate memory for the resulting array
mov eax, 4
mov ebx, 1
mov edx, ecx
int 0x80
mov esi, eax ; Store the address of the resulting array
; Copy array a to the resulting array
mov ecx, a_len
mov edi, esi
rep movsb
; Copy array b to the resulting array
mov ecx, b_len
add edi, ecx
mov esi, b
rep movsb
mov eax, esi ; Return the address of the resulting array
mov esp, ebp
pop ebp
ret
; Extends array a with the elements of array b
two:
mov ecx, b_len
mov edi, a + a_len
mov esi, b
rep movsb
ret
; Prints an array of integers
; ecx - pointer to the array
; edx - length of the array
print_array:
pusha
; Loop through the array and print each element
mov eax, 4
mov ebx, 1
mov esi, ecx
mov ecx, edx
mov edx, 1
add edx, '0'
sub ecx, 1
add ecx, '0'
print_loop:
mov al, byte [esi]
cmp al, ecx
jne print_element
mov al, 10 ; Print a newline character after the last element
call print_character
jmp print_end
print_element:
call print_character
inc esi
dec edx
cmp edx, 0
jne print_loop
print_end:
popa
ret
; Prints a single character
; al - character to print
print_character:
pusha
mov eax, 4
mov ebx, 1
mov ecx, esp
mov edx, 1
int 0x80
popa
ret
무엇을 보고 메모리를 판단 해야 될까??
; Calculate the length of the resulting array
mov ecx, a_len
add ecx, b_len
; Allocate memory for the resulting array
mov eax, 4
mov ebx, 1
mov edx, ecx
int 0x80
mov esi, eax ; Store the address of the resulting array
이 부분 이다.
아래는 메모리 계산하는 방법이다.
a_len과 b_len 변수를 더하여 새로운 배열의 길이(ecx)를 계산한다.
int 0x80 시스템 호출을 사용하여 메모리를 할당한다. 이때 메모리 할당은 edx 레지스터에 새로운 배열의 길이가 전달된다.
메모리 할당이 완료되면 할당된 주소가 eax 레지스터에 저장됩니다.
따라서 one() 함수에서 할당되는 메모리의 크기는 eax 레지스터에 저장된 주소의 범위에 해당 해야한다.
반면에 two() 함수는 배열 a를 확장하기 위해 메모리를 추가로 할당하지 않는다. 대신, 이미 할당된 a 배열의 뒤에 b 배열의 요소들을 복사합니다. 따라서 two() 함수는 이미 할당된 배열 a의 크기에 따라 메모리 사용량이 결정된다.
one() 함수에서 새로운 배열의 길이(ecx)는 a_len과 b_len의 합이다.
따라서 a_len이 10이고 b_len이 5라고 가정하면, ecx는 15이다.
메모리 할당은 int 0x80 시스템 호출을 통해 이루어진다.
메모리 할당의 크기는 edx 레지스터에 전달되는데, 이 값은 새로운 배열의 길이이다. 여기서 edx는 15입니다.
따라서 대략적으로 one() 함수가 약 15바이트의 메모리를 할당하는 것으로 예상할 수 있습니다.
two() 함수는 이미 할당된 a 배열을 확장하기 때문에 별도의 메모리 할당이 발생하지 않는다.
따라서 two() 함수는 a 배열의 크기에 따라 메모리 사용량이 결정된다,
즉 one() 함수가 two() 함수 보다 메모리를 더 많이 할당 한다.
728x90
'Python' 카테고리의 다른 글
AWS S3 이미지 파일 업로드 하기 (0) | 2023.06.20 |
---|---|
AWS S3 이미지 파일 압축하여 다운로드 하기 (0) | 2023.06.20 |
aiohttp로 하는 비동기 HTTP 요청 (0) | 2023.05.13 |
UUID란? (0) | 2023.05.05 |
Django formset, is_valid 란 무엇인가? (0) | 2023.04.22 |