2017-11-28 12 views
1

현재 어셈블러 프로그램을 작성하는 방법을 이해하려면 다음 블로그를 읽고 있습니다. 나는 블로그의 모든 것을 이해하지만, 한 가지를 생각할 수는 없습니다.64 비트 포인터를 x86_64 어셈블러에서 4 바이트에 맞출 수있는 방법

https://www.recurse.com/blog/7-understanding-c-by-learning-assembly

코드 : 우리가 제로 -0x4로 (%의 RBP)를 쓸 수있는 이유

0x0000000100000f50 <main+0>: push %rbp 
0x0000000100000f51 <main+1>: mov %rsp,%rbp 
0x0000000100000f54 <main+4>: mov $0x0,%eax 
0x0000000100000f59 <main+9>: movl $0x0,-0x4(%rbp) 

는 이해가 안 돼요. 1 번 줄에서 스택에 % rbp 레지스터에 저장된 포인터를 푸시했습니다. % rbp 레지스터 크기가 64 비트이므로 나중에 -0x4 (% rbp)가 아닌 -0x4 (% rbp) 위치에 0을 씁니다. 스택은 -0x4 (% rbp)가 아닌 4 바이트 (32 비트)입니다.

누구든지 설명 할 수 있습니까?

미리 감사드립니다.

+0

64 비트 레지스터를 저장하지 않고 32 비트 상수를 저장하고 있습니다. – gnasher729

답변

2

이후 %rsp%rbp-0x4(%rbp)은 적색 영역에있어서, 스택 포인터이하이며,이 점에서 동일하다. 이것은 시그널 핸들러 (그리고 디버거)가 다루지 않는 영역이므로 스택 포인터 아래에 있더라도 사용할 수 있습니다.

그리고 movl 명령어는 64 비트 기계어가 아닌 32 비트 양인 int을 저장합니다.

+0

답변 해 주셔서 감사합니다. 그래서 movl 명령은 -0x0 (% rbp)에서 -0x4 (% rbp)까지의 addreses에 기록합니까? 이전에 -0x4 (% rbp)에서 -0x8 (% rbp)까지의 주소에 쓰는 것으로 생각했습니다. 우리가 그 후 쌓아 올리면 무엇이 일어날까요? – oliva5

+0

@ oliva5'movl'은 항상 4 바이트를 씁니다. 8 바이트를 쓰는 'movq'입니다. 나중에 스택에 무언가를 밀면 밀어 넣기 전에 이동 한 항목을 덮어 씁니다. 특별한 행동은 없습니다. – fuz

+0

좋아, 이제 알 겠어. 대답 해줘서 고마워. – oliva5