리눅스 커널안에 어셈코드 관련 질문입니다.
안녕하세요 ^^
커널소스 linux/arch/i386/kernel/entry.S 에 보면
첫부분에
여기부터
Stack layout in 'ret_from_system_call':
ptrace needs to have all regs on the stack
if the order here is changed, it needs to be
updated in fork.c:copy_process, signal.c;do_signal,
ptrace.c and ptrace.h
0(%esp) - %ebx
4(%esp) - %ecx
8(%esp) - %edx
C(%esp) - %esi
10(%esp) - %edi
14(%esp) - %ebp
18(%esp) - %eax
1C(%esp) - %ds
20(%esp) - %es
24(%esp) - orig_eax
28(%esp) - %eip
2C(%esp) - %cs
30(%esp) - %eflags
34(%esp) - %oldesp
38(%esp) - %oldss
"current" is in register %ebx during any slow entries.
여기까지 주석처리되어있고
EBX = 0x00
ECX = 0x04
EDX = 0x08
ESI = 0x0C
EDI = 0x10
EBP = 0x14
EAX = 0x18
DS = 0x1C
ES = 0x20
ORIG_EAX = 0x24
EIP = 0x28
CS = 0x2C
EFLAGS = 0x30
OLDESP = 0x34
OLDSS = 0x38
이렇게 코딩되어있습니다
저로써는 이해가 잘안돼 혹시 왜 이렇게 정의해놨는지
조언해주시면 감사하겠습니다~
도대체 이걸 어디에 쓰려는건지 ㅠㅠ
인텔에서 쓰는 레지스터 15개를 어떤곳에 쓰기에
이렇게 차곡차곡 해놨는지... 이렇게 해야하는 이유가 있는지요
이 지금 되어있는 위치를 섞으면 어떻게 되는지;;
system call은 인터럽트입니다.
인터럽트의 개념을 알고 계신다면 왜 스택상에 CPU의 레지스터를 모두 보존하는지 이유를 알 겁니다. 그리고 system call에서는 몇몇 레지스터를 parameter로 사용합니다. 따라서 스택에 보존하는 레지스터의 순서를 바꾸게 된다면 최악의 경우 system call에 관련된 함수들을 다 뜯어 고쳐야 하는 결과를 초래하겠죠.
답변 감사드립니다
먼저 답변감사드립니다!!
system call이 인터럽트라는건 알고 있습니다. 좀더 추가로 말씀드리겠습니다.
EBX = 0x00
ECX = 0x04 ... 등등 써있는데 뒤에 상수값이 스택상에 오프셋 위치를 나타나고
있는건가요??
잘 이해가 안되는건 어셈 파일에 덩그러니 EBX ..ECX.. EDX 이렇게 나와있는데
어디 메모리에 주소를 C언어로 치면 #define 하고 있는건지
어느 스택에 오프셋을 나타내고 있는지... 잘 이해가 되지 않습니다.
음...답변내용을 계속 보고 느낀점은
혹시나 저게 스택에 오프셋값이어서 스택에 저에 해당하는 레지스터값을 저장하려면
저 오프셋에 저장해야한다?? 이런생각도 문뜩드네요.
맞는지 아닌지는 명확히 모르겠지만...
EBX = 0x00 이런 식으로
EBX = 0x00
이런 식으로 되어 있는 부분은 GNU as의 매크로 선언입니다. 스택 프레임의 시작 지점에서의 옵셋으로 메모리 접근을 하면 해당 레지스터가 저장된 위치를 얻을 수 있는 겁니다.
실제로 사용하는 걸 보면
movl EBX(%edx), %ebx
와 같이 옵셋으로 사용하는 걸 알 수 있습니다.
어셈블리에 대한 이해가 선행되지 않으면 이해하기 힘들기 때문에 커널 진입부분을 해석하려면 최소한 i386 어셈블리(AT&T 문법으로 된 것으로..)와 C언어의 Calling Convention을 학습하시기 바랍니다.
댓글 달기