포인터 함수 메모리 그림 질문하겠습니다.
조회수 433회
main 함수에서 포인터를 지정한 후 정의된 다른 함수를 불러옵니다. 그리고 그 함수에 포인터의 주소를 대입하면 메모리 그림에서는 다른 함수를 정의할때 괄호 안에 썼던 예를 들면 int* ptr이런게 실제로 생기는 건가요 아니면 int* ptr 은 그냥 가상의 변수인가요?
1 답변
-
코딩해놓은 한줄이 실제로 있는가 가상의 변수인가를 생각하실 필요가 없는게 프로그램 사전에 정의되지 않는 변수명이 없으면 동작이 안되는것만 생각하시면 편하실거라 생각되는데 :(
솔직히 말해서 질문 내용에 있어서
포인터
가 언급되는건 해당 질문 내용에 있어 무관한 내용인거 같고 예시가 없어서 처음에 질문글 보고 햇갈렸었네요..결론부터 말씀드리면 해당 변수가 들어갈 공간은 해당 함수에 진입할때 같이 생성됩니다.
#include <stdio.h> #include <stdlib.h> void test(int *abc) { printf("%d\n", *abc); } int main() { int *ptr; ptr = (int *)malloc(sizeof(int)); *ptr = 123; test(ptr); return 0; }
위와 같은 코드를 디버깅 하여 확인 해보겠습니다
gdb-peda$ disas test Dump of assembler code for function test: 0x000000000000068a <+0>: push rbp 0x000000000000068b <+1>: mov rbp,rsp 0x000000000000068e <+4>: sub rsp,0x10 0x0000000000000692 <+8>: mov QWORD PTR [rbp-0x8],rdi ... 0x00000000000006af <+37>: nop 0x00000000000006b0 <+38>: leave 0x00000000000006b1 <+39>: ret End of assembler dump. gdb-peda$ disas main Dump of assembler code for function main: 0x00000000000006b2 <+0>: push rbp 0x00000000000006b3 <+1>: mov rbp,rsp 0x00000000000006b6 <+4>: sub rsp,0x10 0x00000000000006ba <+8>: mov edi,0x4 ... 0x00000000000006d2 <+32>: mov rax,QWORD PTR [rbp-0x8] 0x00000000000006d6 <+36>: mov rdi,rax 0x00000000000006d9 <+39>: call 0x68a <test> 0x00000000000006de <+44>: mov eax,0x0 0x00000000000006e3 <+49>: leave 0x00000000000006e4 <+50>: ret End of assembler dump.
어셈블리코드를 참고하시면 다른 함수로 들어갈때
- main func mov rax,QWORD PTR [rbp-0x8] mov rdi,rax call test - test func push rbp mov rbp, rsp sub rsp, 0x10 mov QWORD PTR [rbp-0x8],rdi
기존에 돌아갈 주소를 스택에 쌓아두고 새롭게 스택을 구축합니다 그리고
x64 linux calling convention
에 따라rdi
에 해당 변수를 넣고 함수를 호출하죠rdi
값은 동일하고 새로운 함수에 왔으니 새로운 스택을 가지고sub rsp 0x10
을 통하여 새로운 변수를 넣을 공간을 만든 이후에rdi
값을 넣어줍니다.그리고 함수가 종료시에는 해당 함수에서 사용했던 스택공간을 다 비우고 원래 함수가 호출됬던 시점으로 돌아가게 됩니다.
댓글 입력