[Architecture] 메모리 read할때 주소지정 내부구조에 관한 질문
컴퓨터시스템구조(사이텍미디어) 라는 책을 보면
원시적인 컴퓨터를 설계하게 되는데요.. 8080보다 더 이전버젼에 해당하는 머신구조라고 들었습니다.
최종 설계도를 보면
메모리 read를 할때 한 클럭에 이뤄지는데요..AR이라는 address register를 이용합니다. AR의 출력은 항상 메모리의 주소지정부분의 입력으로 들어가고 있습니다.
IR(Instruction register) <- M[AR]
그렇게 때문에 위와같은 명령이 한 클럭으로 가능합니다.
대신 PC(program counter register)를 증가시킨후 다음 명령을 fetch해오려고 하더라도 AR<- PC 를 해준뒤에 메모리를 읽어와야하는 번거로움이 있습니다.
이러한 머신의 구조는 이해가 되는데요..
지금의 머신은 어떻게 구현이 되고 있는지 모르겠습니다.
메뉴얼이 모두 내부로직을 chip으로 뭉뚱그려놔서요..
첫째,
그나마 자세히나온 8086의 구성도를 보면 16bit레지스터로 20bit주소지정을 하기 위한 CS:IP DS:SI 등의 segment+offset 을 해준뒤 physical address를 구하는 로직이 들어가게 되는데요.. 물론 지금은 이렇게 주소지정을 하고 있지는 않지만, 주소지정을 위한 전용 레지스터가 있는가의 여부에 관한 관점에서 봤을때 .. 메모리 주소지정 전용으로 쓰이는 AR과 같은 레지스터는 없는거 같습니다. 따라서 지금의 architecture 에서도 없을것으로 생각됩니다.
만일 여러 레지스터중에 한개의 레지스터값에 의해서 address가 지정이 될 수 있다면 메모리 참조시 마다 주소지정 레지스터를 정해줘야 하는 번거로움이 있을텐데요.. 어떻게 구성이 되고 있는지 궁금합니다.
둘째,어셈명령어중
MOV AX,[BX+10];
이런 명령어의 처리는 회로구현이 어떻게 이뤄지는지 모르겠습니다. BX레지스터를 10증가시킨후 메모리 참조를 하게 되면 BX레지스터의 값이 바뀌기 때문에 문제가 되는데요..
메모리 참조가 가능한 다른 레지스터는 DI 와 SI 레지스터가 있는데 이러한 레지스터도 사용자가 사용을 하고 있을지 모르니 함부로 값을 수정해서 사용할 수 는 없는데요..
원래의 BX값을 메모리로 백업한다고 해도 이 세 레지스터의 값을 또한 수정할 수 없을때는 마찬가지로 불가능하구요..
마지막으로 레지스터로 백업을 하는방법이 있는데 다른 레지스터들도 모두 사용을 하고 있다면 또 문제가 되구요..
BX+10의 계산결과를 어느 특정 레지스터에 저장한뒤에 그 레지스터를 가지고 메모리 주소지정을 하는게 아닌가요 ?
( 결과를 특정레지스터에 기록 안하고 주소지정 한다고 해도 계산 과정에서 최소한 10이라는 상수값은 레지스터에 저장을 해야 할텐데요..결국 어떠한 레지스터든지 사용을 해야 할 것으로 생각됩니다.)
두가지 질문 답변부탁드립니다.
[quote]메모리 주소지정 전용으로 쓰이는 AR과 같은 레지스터는 없는
AR과 같이 단 하나의 address register가 있는 것은 드물지만, 제한적으로 몇개만 쓰일 수 있는 system은 많습니다. x86도 마찬가지 입니다. 이 목적으로 쓸 수 있는 register는 (E)AX, (E)BX, (E)CX, (E)DX, (E)SI, (E)DI 등인데, 전체 다 가능한 것은 아닙니다. 자세한 목록은 x86 reference를 보기 바랍니다. 여기에서 Manuals 섹션에 나온 파일에 자세히 나와 있습니다.
x86을 본지 꽤 오래되서 정답은 아니지만, 답을 말씀드리면, CPU 설계를 어떻게 하느냐에 따라 다릅니다.
BX + 10의 값을 ALU를 통하여 얻고, 이 값이 내부 레지스터에 저장된 상태에서 memory chip의 address로 연결되었을 수 있고 (이 경우 1 clock에 얻기 힘듬), ALU의 결과가 그대로 address line으로 연결되어 memory에 연결되어 있을 수 있습니다 (이 경우 짧은 clock에 가능하나, BX * DI + 10과 같은 복잡한 연산이 힘듬).
또한 10이라는 상수값은 보통 instruction register(책에는 IR 등으로 나와 있을 겁니다.) 에서 바로 뽑아 올 수도 있습니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
답변 감사합니다.^^
레퍼런스 감사합니다.^^
OFFSET을 IR레지스터에서 바로 뽑아내는 방법이 있었군요..
사실 궁극적으로 알고자 했던 부분은
MOV AX,[1000] 과
MOV AX,[BX+10] 이 명령어의 속도 차이었는데요..
답변을 받고보니
첫번째 명령어는 ALU를 거치지 않지만
두번째 명령어는 ALU를 거쳐야 한다는것이 두 명령어의 차이점으로 보입니다. 최소 한클럭이상이 차이가 날것으로 보이는데요..
따라서 회로구현이 시스템마다 다르긴 하겠지만
어떠한 구현이든 두 명령어중에 두번째 명령어가 당연히 느릴 수 밖에 없다는 생각이 듭니다.
이렇게 생각하는게 맞을까요?
Re: 답변 감사합니다.^^
사실은 느리지도 않습니다. ^^;
CPU마다 다르겠지만, 대부분 한 개의 명령어를 처리하는 데에 ALU 를 거치지 않고 가느냐 ALU를 거치느냐로 시간이 달라지진 않습니다. 또한 주소지정 방식에 따라 시간이 달라지는 경우는 없습니다. 다만 외부 메모리에 접근하려 할 때 생기는 지연시간이 있기 때문에 시간차가 생기는 것 뿐입니다.
만일 외부 보조 연산 프로세서를 사용하게 되는 경우라면 명령 실행 시간이 길어지는 것은 어쩔 수 없겠지만요... ^^;
답변감사합니다.
이 부분을 살펴보게된 계기는..
프로그래밍 언어론(홍릉과학출판사) 책을 보면
지역변수는 간접 주소지정 방식 이고
정적지역변수의 접근은 직접주소지정방식이라고 나와있습니다.
또한
대부분의 컴퓨터에서 간접주소지정 방식은 직접주소지정 방식보다 느리다 라고 나와있습니다.
그럴것 같다는 생각은 들었지만 정확한 이유를 알아보기 위해
간단한 코드의 disassembly 코드를 봤습니다.
먼저 지역변수로 선언된 s에 0xff값을 넣고 디버그 해보면
8: s= 0xFF;
00401028 mov dword ptr [ebp-4],0FFh
이런식으로 ebp를 기준으로 offset을 적용하는 레지스터 간접주소지정방식으로 구현되어 있었습니다.
(참고로 vc6.0(디버그모드)에서 테스트 한것입니다.)
전역변수 s에 0xff값을 넣는 경우엔
8: s= 0xFF;
00401028 mov dword ptr [_s (004227b8)],0FFh
이런식으로 직접주소지정방식으로 구현하고 있었습니다.
이는 책의 내용과 일치했고,
속도에 관한 차이는 아주 작은 차이겠지만 그래도 언급을 하고 있기때문에.. 알아보고 싶었습니다.
댓글 달기