태초의 프로그래밍 언어 어셈블리

assembly, 8086, x86

변수의 주소값 알아내기

LEA라는 새로운 명령어를 말씀드리겠습니다. 특정 변수의 주소를 알아내는 명령입니다.
 
ORG 100h
MOV AL, VAR1 ; check value of VAR1 by moving it to AL.
LEA BX, VAR1 ; get address of VAR1 in BX.
MOV BYTE PTR [BX], 44h ; modify the contents of VAR1.
MOV AL, VAR1 ; check value of VAR1 by moving it to AL.
RET
VAR1 DB 22h
END
 
var1의 값을 그대로 읽는게 아니라 var1이라는 변수가 위치한 메모리 주소를 알아내는 것입니다. 주소를 저장하는 레지스터(BX, SI, DI, BP)는 메모리 포인터같이 대괄호안에서만 사용될 수 있다는 것을 기억하시기 바랍니다.
변수의 주소를 알아내는 것은 중요한 일입니다. 지금은 생각하지 않지만 앞으로 함수를 만들게되면 변수의 주소를 다른 함수로 넘겨서 그 함수에서 변수의 값을 바꾸게 할 것입니다. 변수의 값을 함수에게 전달하면 그 함수는 변수의 값을 바꿀 수가 없습니다. 그 이유는 나중에 함수를 설명할 때 말씀드리겠습니다. mov로 주소 값을 다루는 동작을 설명하면서 lea도 유사한 동작을 하므로 같이 설명했습니다. mov와 lea가 비슷하다고 생각되시면 큰일납니다. 다시한번 예제를 잘 읽어보시고 emu8086으로 실행해보세요. 하나는 변수의 값을 바꾸는 것이고 하나는 변수의 위치를 알아내는 것입니다.

댓글

댓글 본문
작성자
비밀번호
  1. gurugio
    byte enable이 뭔지 잘 모르겠습니다.

    lea eax, dword ptr ss:[esp-4]를 실행하면 그냥 ss:esp-4의 값이 저장될것 같습니다.
    [ss:esp-4]가 가르키는 메모리의 주소를 말하니까 ss:esp-4값 그대로가 될것 같습니다.
    lea 명령은 저도 자주 헷갈리는 명령인데요 확실하게는 해봐야알것 같은데 32비트 x86을 실험해볼 환경이 없네요.
    대화보기
    • starlee3
      항상 친절한 답변 감사합니다. 위 글을 읽다가 갑자기 궁금해서 질문 드립니다 ?
      x86경우
      16비트나 32비트경우
      address는 구성요소는 byte lane(byte enable)+ segment번지+offset번지로 구성되어 있다고하는데...


      lea eax dword ptr ss:[eps-4]

      이런명령일 경우 eax레지스터에 저장되는것이 byte enable는 빼고 offset 번지만 저장되나요?
      같이 저장되나요? 둘다 저장되나요?
    • gurugio
      1. 최신 프로세서는 아무 레지스터나 다 주소값을 넣어서 사용할 수 있습니다.
      2. _a$는 컴파일러가 만든 오프셋값입니다. [ebp+_a$]와 같다고 생각하면 되는데요 변수 a가 스택에서 ebp-8 지점이라고 하면 _a$은 -8이 됩니다.
      대화보기
      • starlee3
        32비트 컴퓨터로 사용하는데 ...

        옜날에 볼랜드c++,터보c 컴파일러만 사용하다가 vc++ 취미로 최근에 만져서 모르겟고 도통 감이 안오는데
        삽질 하다가,vc++2010으로 디스 어셈블 해보니까!! 코드가 이렇게 나오는데요...

        void main()
        {
        int a;
        int * pt;
        pt=&a;
        *pt=124;
        }


        int a;
        int * pt;
        pt=&a;

        lea eax, DWORD PTR _a$[ebp]
        mov DWORD PTR _pt$[ebp], eax

        *pt=124;

        mov eax, DWORD PTR _pt$[ebp]
        mov DWORD PTR [eax], 124

        함수 내부이니까 stack segment 란 ebp를 사용했는데



        이해가 안가는것은 ? [eax] 를 간접주소로 사용하는데요?? 왜 그렇죠?? 포인터는 [eax] 를 사용해도?되는가?아~쩝쩝~
        _a$[ebp] ,_pt$[ebp] _a$, _pt$ 는 무슨의미죠? 옜날 cpu랑 지금 cpu랑 아키텍처가 틀린것?인가요?
      • gurugio
        포인터는 값 자체가 주소이니까요
        mov ebx, a
        mov byte ptr [ebx], 123
        이렇게 됩니다.
        대화보기
        • starlee3
          재 질문 합니다!! ㅋ ^^; 질문을 할려면 묻는 요지를 자세히 써야하는데...죄송~!! 반성~

          vc++(visual c++ 2010 express )로 디스어셈블 하니까 남들이 ,
          chr i=21
          chr*a=&i
          *a=123

          printf("%d",*a);



          chr *a =&i 문장에서

          &i는

          lea eax,dword ptr EDS:[i]


          4바이트 크기에 i번지 주소를 load effective address하여 eax 에 넣는다.

          load effectvie address 의미를 찾아 보니까 이말은 i 번지를 CPU내 EDS 레지스터 selector값말고,
          EBX 에 offset 주소값(실효번지EA)를 eax 레지스터 넣는다는 말 같은데요...


          chr *a=의미는

          mov dword ptr [a],eax

          즉 4바이트 크기에 a번지(메모리에) eax값(주소를) 넣는다 의미같은데요.



          다음 문장 ~!!!!!

          *a=123


          의 어셈블리 코드로 어떻게 되냐 질문입니다? (혼자생각,디스어셈블해서 코드를 봐야하는데~설치하는법을 몰라서용 ㅋ)

          mov eax,dword ptr [a]
          mov ebx,eax
          mov byte ptr [ebx],123 인가요? ??

          이렇게 써 보니까 32비트가 8비트로 되었네용 ~!!

          즉 * 연산자가 기능이 어셈블리로 어떻게 표현되나 질문입니다?

          PS)c포인터는 참 표현이 한편의 시 한편같다는 느낌이 드네요!!
          나는 친구랑 2014년 6월 14일 저녁 08:23분에 신촌에서 민속주점에서
          키 189 안경낀 친구랑 술 먹고 12시에 택시를 타고 집에 와서 쿨쿨 잤다를

          토요일날 저녁에 술먹고 집에 왓따 표현(약올리는것)같아용~!!!


          메트릭스 눈으로 안보이네용 !!!
        • gurugio
          죄송하지만 질문이 뭔지 잘 이해가 안됩니다.

          일단 이런 코드를 생각해보겠습니다.
          int a;
          int *pa = &a;
          *pa = 10
          이게 컴파일되면 이정도로 될것같습니다.

          lea ebx, a
          mov pa, ebx 여기까지가 pa = &a 입니다.

          mov ebx, pa
          mov dword ptr [ebx], 10 이렇게하면 a = 10이 됩니다.

          *pa = 10 이나 a = 10 이나 같은거 아닌가요?
          어떻게하든 a에 10 이 저장되면 되는거니까요.
          대화보기
          • starlee3
            int a;
            int* pa;

            pa=&a ;
            *pa=10 ;

            할경우



            lea eax,dword ptr [a]

            selecter주소가 아닌 offset 주소를 eax레지스터에 넣고

            move dword ptr[pa],eax

            eax안에 주소값을 메모리 번지위치에 write 하라

            명령인데!!



            *pa=10

            은 어셈블러로 어떻게 표현되나요??? pa는 offset 이고 , *는 ds ss 를 말하는것인가요?

            move dword ptr[pa], 10 ???? 이거는 int a=10 명령인데용? ??? 쩝???
          graphittie 자세히 보기