Effective Address란?

조동현 2013.10.13 02:36 조회 수 : 6416 추천: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 문법을 썼기 때문에 "[]"의 형태를 띠고 있었던 것이었습니다.
XE Login