Effective Address란?

조동현 2013.10.13 02:36 조회 수 : 6422 추천:2

LEA(Load Effective Address) Instruction을 만날 때마다 잘 와닿지 않았던 이유중 하나는 Effective Address가 대체 뭘 말하는 지를 알지 못했기 때문이었던 것 같습니다. 저 Effective Address라는 것이 뭘까… 하고 조사를 해보니 이제 조금은 알 것 같네요.


1. Effective Address

먼저 IA-32 Instruction에서 메모리를 참조하는 피연산자(operand)는 다음과 같은 구조를 가지게 됩니다.



Screenshot from 2013-10-13 02:05:39.pngScreenshot from 2013-10-13 02:05:56.png



1.1 Segment Selector


Memory Operand를 구성하는 첫번째 요소인 Segment Selector는 현 Operand를 포함하고 있는 세그먼트를 가리키게 됩니다. 32비트 모드냐 64비트 모드냐에 따라서 약간 차이가 있습니다.

 

32비트 protected 모드의 경우에는, 이전 스터디에서 보았던 것처럼 GDT에 Segment Descriptor들을 정의해 놓고 이곳에서의 13bit의 index와 3bit의 flag로 구성되게 됩니다.


Screenshot from 2013-10-13 02:11:43.png


하지만 64비트 모드에서는 Segmentation이 거의 사용되지 않는다고 하네요.1 프로세서가 CS, DS, ES, SS를 0으로써 처리한다고 합니다.(그러나 FS와 GS는 예외라고 하네요). 실제로 이번에 분석중인 head_64.S에서도 ds/es/ss/fs/gs를 명시적으로 0으로 만드는 부분도 있었습니다.

1.2 Offset

Memory Operand를 구성하는 두번째 요소인 Offset은 다음의 네가지 부분으로 구성됩니다.


Displacement
8/16/32비트 값
Base
임의의 레지스터 안에 있는 값
Index
임의의 레지스터 안에 있는 값
Scale factor
Index에 곱해질 2, 4 또는 8


Screenshot from 2013-10-13 02:06:20.png


네가지를 가지고 위와 같이 계산된 결과 offset을 바로 Effective Address라고 부른다고 하네요. 다 아셨던 부분일 수도 있지만.. Intel 메뉴얼에 이렇게 정의되어있을 줄은 몰랐네요.


The offset which results from adding these components is called an effective address.2


1.2.1 Offset(Effective Address) in GNU Assembler

우리가 분석하고 있는 Linux에서 사용되는 GNU Assembler에서 이 Offset(Effective Address)를 어떻게 정의할 수 있는지 알아봅시다. GAS 메뉴얼에서 x86 파트를 한번 찾아보았습니다.3


An Intel syntax indirect memory reference of the form

        section:[base + index*scale + disp]

is translated into the AT&T syntax

        section:disp(base, index, scale)


저희는 AT&T 스타일을 쓰고 있기 때문에4 아래와 같이 네 부분을 괄호와 쉼표로 구성하게 됩니다. 왜 갑자기 linux 분석에 들어와서 "[]"로 메모리 접근하는 연산이 없어졌나 했더니, 문법이 두 종류 였었던 것이네요.


2. MOV vs LEA

결론부터 말씀드리면, MOV로 위의 4개의 인자를 계산하여 Immediate Operand로써 대입시키나, LEA로 한번에 계산하나 똑같다고 할 수 있습니다. 다만 한번에 하는게 훨씬 좋겠죠? 하지만 Memory Operand로써 Mov로 쓰게 되면, Memory Operand가 참조하고 있는 메모리의 값을 Destination Operand로 대입시키게 됩니다.


--

1   3.7.4.1 Segmentation in 64-Bit Mode, Intel 64 and IA-32 Architectures Software Developer's Manual Volume 1
2   3.7.5 Specifying an Offset, Intel 64 and IA-32 Architectures Software Developer's Manual Volume 1
이번 스터디에 나왔던 RIP 관련 내용도 여기에 나오는 듯 합니다. "1234(%rip)"는 Points to the address 1234 bytes past the end of the current instruction."을 의미한다고 예제로 나오네요.
Unix가 AT&T Bell 연구소에서 만들어졌기 때문에 Unix 월드에서는 AT&T 문법을 많이 쓴다고 하네요. 저희가 공부했던 "만들면서 배우는 OS 커널의 구조와 원리" 책에서 쓰고 있는 NASM이 바로 이 Intel 문법을 썼기 때문에 "[]"의 형태를 띠고 있었던 것이었습니다.
번호 제목 글쓴이 날짜 조회 수
공지 [공지] 커널 스터디 관련 Q&A 게시판 입니다. [5] woos 2016.04.09 2199
1745 setup.c 파일의 cacheid_init 함수 [1] file HyunGyu 2013.11.05 72312
1744 Vol.1의 CMPS ~ CVTPD2PS 입니다. 늦어서 죄송합니다. file 지현구 2007.03.10 64221
1743 as86(1) - Linux man page 입니다. 김민석 2010.04.30 36679
1742 lilo.c에서 !! 관한 토론? [6] 오시리스 2011.07.25 34354
1741 [ARM중] 1차 분석 복습 [5] file 홍문화 2011.08.08 33712
1740 ZONE_DMA, ZONE_NORMAL, ZONE_HIGHMEM (미완성) 구본규 2013.10.15 32786
1739 fork() 함수가 리턴을 두번하는 이유 설명 [2] 커널B조 2016.05.07 30233
1738 task_struct 구조체입니다. [1] file 아폴로 2013.04.30 29856
1737 ARM 프로세서 모드 [7] 홍문화 2011.06.08 26499
1736 BIOS 를 통하여 PCI configuration space를 액세스하는 방법 지현구 2007.08.12 22867
1735 파이프라인과 익셉션의 관계 관련 블로그 주소입니다. 이한울 2012.05.26 22081
1734 buildroot 사용법 [1] 구본규 2012.07.20 20243
1733 [x86] 스터디때 나왔던 cpu_dev 문제 [2] file pororo 2012.02.19 18434
1732 페이지 테이블에 주소 변환 정보가 채워지는 원리 [16] 홍문화 2011.07.12 16326
1731 odroid bootlog 입니다 박장운 2010.08.14 15560
1730 명령어 정리 - 늦어서 죄송.. 송형주 2007.03.09 14527
1729 Linux booting 과정 (start_kernel() 함수 전까지) 관련 참고자료들 모음 file 지현구 2007.04.27 14328
1728 분석 환경 구축 실습 [11] file 권석민 2013.05.19 14204
1727 [x86] 가족번호 [2] pororo 2012.02.27 13914
1726 LVM에 대해 간략하게 정리했습니다. [2] file 조성진 2013.05.07 13825
XE Login