"FS"/ "GS"레지스터의 용도는 무엇입니까?


103

그래서 다음 레지스터와 그 용도가 무엇인지 알고 있습니다.

  • CS = 코드 세그먼트 (IP에 사용됨)

  • DS = 데이터 세그먼트 (MOV에 사용됨)

  • ES = 대상 세그먼트 (MOVS 등에 사용됨)

  • SS = 스택 세그먼트 (SP에 사용됨)

그러나 다음 레지스터는 어떤 용도로 사용됩니까?

  • FS = "파일 세그먼트"?

  • GS = ???

참고 : 난 하지 특정 운영 체제에 대해 물어 - 나는 그들이이 CPU에 의해 사용하기위한 있었는지에 대해 부탁 해요, 무엇이든합니다.


24
내가 아는 한,이 둘의 F와 G는 아무것도 의미하지 않습니다. 단지 6 개의 사용자 지정 가능한 세그먼트 레지스터를위한 CPU (및 명령어 세트) 공간이 있었고 누군가는 "S"tack 세그먼트 외에 문자 "C"와 "D"(코드 및 데이터)를 발견했습니다. "E"는 "추가"세그먼트 였고 "F"와 "G"가 뒤따 랐습니다.

3
그 당시에 당신이 거기에 있지 않았다면 다른 사람의 머리 속에서 무슨 일이 벌어지고 있는지 알기가 항상 어려웠을 것입니다.
torek

20
BS 레지스터로 얼마나 재미 있었는지 생각해보십시오. :-}
Ira Baxter

5
저는 항상 GS를 "그래픽 세그먼트"로 사용했습니다. :-)
Brian Knoblauch

2
"G"eneral "S"egment는 어떻습니까?
SS Anne

답변:


110

그들이 의도 한 것과 Windows 및 Linux에서 사용되는 용도가 있습니다.

세그먼트 레지스터의 원래 의도는 프로그램이 독립적이고 영구적 인 가상 저장소의 일부가되도록 의도 된 여러 다른 (대형) 메모리 세그먼트에 액세스 할 수 있도록하는 것이 었습니다. 이 아이디어는 파일을 단순히 주소 지정이 가능한 메모리 세그먼트로 취급 하는 1966 Multics 운영 체제 에서 가져 왔습니다 . BS 없음 "파일 열기, 레코드 쓰기, 파일 닫기", 더티 페이지 플러싱으로 "이 값을 해당 가상 데이터 세그먼트에 저장".

현재 2010 년 운영 체제는 거대 한 단계 뒤로 물러 서기 때문에 "Eunuchs"라고 불립니다. 당신은 당신의프로세스 공간의 단일 세그먼트 소위 "플랫 (IMHO 둔) 주소 공간"을 제공 할 수 있습니다. x86-32 시스템의 세그먼트 레지스터는 여전히 실제 세그먼트 레지스터에 사용할 수 있지만 아무도 신경 쓰지 않았습니다 (전 인텔 사장 인 앤디 그 로브는 지난 세기에 인텔 엔지니어들이 에너지를 소비하고 이 기능을 구현하기위한 그의 돈은 아무도 사용하지 않을 것입니다. Go, Andy!)

AMD는 64 비트로 이동하면서 Multics를 선택 항목으로 제거해도 상관하지 않기로 결정했으며 (자선적인 해석이며, Unariable 한 것은 Multics에 대한 단서가 없다는 것입니다) 64 비트 모드에서 세그먼트 레지스터의 일반 기능을 비활성화했습니다. 스레드 로컬 저장소에 액세스하려면 스레드가 여전히 필요했고 각 스레드에는 즉시 액세스 할 수있는 스레드 상태 어딘가 (예 : 레지스터) ... 스레드 로컬 저장소에 대한 포인터가 필요했습니다. Windows와 Linux는 모두 32 비트 버전에서 이러한 목적으로 FS와 GS (설명에 대해 Nick에게 감사드립니다)를 사용했기 때문에 AMD는 64 비트 세그먼트 레지스터 (GS 및 FS)를 기본적으로이 목적으로 만 사용하도록하기로 결정했습니다. 프로세스 공간의 어느 곳이든 가리켜 야합니다. 애플리케이션 코드가로드 할 수 있는지 여부는 알 수 없습니다.

각 스레드의 메모리 맵이 스레드 로컬 스토리지 ([세그먼트] 레지스터 포인터가 필요하지 않음) 인 절대 가상 주소 (예 : 0-FFF)를 갖도록 만드는 것이 구조적으로 더 예뻤을 것입니다. 1970 년대에 8 비트 OS에서이 작업을 수행했으며 작업 할 또 다른 큰 레지스터 스택을 갖는 것처럼 매우 편리했습니다.

따라서 세그먼트 레지스터는 이제 부록과 비슷합니다. 그들은 흔적적인 목적을 가지고 있습니다. 우리의 집단적 손실에.

역사를 모르는 사람들은 그것을 반복 할 운명이 아닙니다. 그들은 멍청한 일을 할 운명에 처해 있습니다.


11
@supercat : 65536 배 더 많은 저장 공간을 처리 할 수있는 더 간단하고 뛰어난 체계는 세그먼트 레지스터를 하위 16 비트의 전체 상위 16 비트 확장으로 처리했을 것입니다. 이는 본질적으로 286, 386과 같습니다. 그리고 Multics는했습니다.
Ira Baxter

4
@IraBaxter :이 접근 방식의 문제는 80286 스타일 세그먼트가 각 세그먼트에 많은 객체를 저장해야하는 것보다 충분히 높은 오버 헤드를 가지므로 모든 포인터에 세그먼트와 오프셋을 모두 저장한다는 것입니다. 반대로 메모리 할당을 최대 16 바이트의 배수로 반올림하려는 경우 8086 스타일 분할을 사용 하면 개체를 식별하는 수단으로 세그먼트 만 사용할 수 있습니다 . 최대 16 바이트의 반올림 할당은 1980 년에 약간 성가신 일 이었지만 각 개체 참조의 크기를 8 바이트에서 4 바이트로 줄이면 오늘날 승리를 나타냅니다.
supercat

3
이러한 레지스터 최신 운영 체제에서 사용됩니다. 그들은 대부분 작업 제어 블록에 대한 정보를 가리키는 데 전념합니다. 적어도 현재 x86 칩에 사용할 수있는 두 가지 주요 OS에서. 그리고 원래 의도에 대해서도 더 이상 "일반적인 목적"이 아니기 때문에 많이 사용할 수 없습니다. x86-64 시스템에서는 스레드 제어 블록에서 액세스 할 수있는 정보가 필요할 때까지 존재하지 않는 것처럼 가장하는 것이 좋습니다.
Ira Baxter

5
부록 비유는 구식 과학에 근거하여 정말 좋지 않습니다. 그것은 면역 체계와 관련이 있으므로 확실히 "흔적"이 아닙니다 . 그것은 실제 게시물을 손상시킵니다. 그 외에는 좋은 반응입니다.
code_dredd

5
세그먼트 메모리와 플랫 메모리의 재미 있고 홀드 금지 처리에 감사드립니다 :) 6809 (페이징 메모리 포함 및 제외), 6502, z80, 68k 및 80 [123]? 86에 코드를 작성 했으므로 내 관점은 기억은 공포의 쇼이고 역사의 쓰레기통에 맡겨서 기쁩니다. thread_local 데이터의 효율적인 액세스를 위해 FS 및 GS를 사용하는 것은 역사적 오류의 의도하지 않은 결과입니다.
Richard Hodges

44

레지스터 FSGS세그먼트 레지스터입니다. 프로세서 정의 목적이 없지만 대신 OS가 실행하는 목적이 있습니다. Windows 64 비트에서 GS레지스터는 운영 체제 정의 구조를 가리키는 데 사용됩니다. FS그리고 GS일반적으로 액세스 스레드 특정 메모리에 OS 커널에 의해 사용됩니다. Windows에서 GS레지스터는 스레드 별 메모리를 관리하는 데 사용됩니다. Linux 커널은 GSCPU 특정 메모리에 액세스 하는 데 사용 합니다.


1
OS 정의 목적으로 사용하거나 *dest++ = lookup[*src++];dest, lookup 및 src가 관련되지 않은 세 위치에 있으면 다소 어색한 작업을 수행해야하는 코드를 용이하게하기위한 것입니다.
supercat 2013-09-17

8
Windows FS에서는 실제로 스레드 특정 저장 소용입니다. 여기에서 FS가 가리키는 블록의 문서화 된 맵을 참조하십시오. en.wikipedia.org/wiki/Win32_Thread_Information_Block
Nedko

2
Windows 뿐만이 아닙니다. GS는 OS X의 TLS에도 사용됩니다. GS는 컨텍스트 전환 중에 시스템 구조를 추적하기 위해 64 비트 커널에서도 사용됩니다. OS는 그 효과를 위해 SWAPGS를 사용할 것입니다.
동부 표준시

13

FS 는 Windows 프로세스의 스레드 정보 블록 (TIB)을 가리키는 데 사용됩니다.

하나의 전형적인 예는 ( SEH )에 콜백 함수에 대한 포인터를 저장하는 것입니다 FS:[0x00].

GS 는 일반적으로 스레드 로컬 저장소 (TLS)에 대한 포인터로 사용됩니다. 이전에 보았을 수있는 한 가지 예는 스택 카나리아 보호 (stackguard)입니다. gcc에서는 다음과 같은 내용을 볼 수 있습니다.

mov    eax,gs:0x14
mov    DWORD PTR [ebp-0xc],eax

2
이것은 실제로 질문에 대한 답이 아닙니다. 질문은 주 : 특정 운영 체제에 대해 묻는 것이 아니라 CPU에서 사용하도록 의도 된 것이 무엇인지 묻는 것입니다.
Michael Petch

10
난 그냥이 질문을 읽는 사람들을위한 좋은 정보로 이것을 추가 할 알고 나중에 @MichaelPetch / SO에이야
zerocool

3

인텔 매뉴얼에 따르면 64 비트 모드에서 이러한 레지스터는 일부 선형 주소 계산에서 추가 기본 레지스터로 사용하기위한 것입니다. 나는 이것을 3.7.4.1 절 (4 권 세트의 86 페이지)에서 가져왔다. 일반적으로 CPU가이 모드에있을 때 선형 주소는이 모드에서 분할이 자주 사용되지 않기 때문에 유효 주소와 동일합니다.

따라서이 플랫 주소 공간에서 FS 및 GS는 로컬 데이터뿐만 아니라 특정 운영 체제 데이터 구조 (페이지 2793, 섹션 3.2.4)를 처리하는 역할을합니다. 따라서 이러한 레지스터는 운영 체제가 사용하도록 의도되었지만 특정 설계자 결정.

32 비트 및 64 비트 모드 모두에서 재정의를 사용할 때 흥미로운 속임수가 있지만 여기에는 권한있는 소프트웨어가 포함됩니다.

"원래 의도"의 관점에서 볼 때 추가 레지스터라는 것 외에는 말하기가 어렵습니다. CPU가 실제 주소 모드 에있을 때 이는 프로세서가 고속 8086으로 실행되는 것과 같으며 이러한 레지스터는 프로그램에서 명시 적으로 액세스해야합니다. 진정한 8086 에뮬레이션을 위해 가상 8086 모드 에서 CPU를 실행 하고 이러한 레지스터는 사용되지 않습니다.


2

TL; DR;

"FS"/ "GS"레지스터의 용도는 무엇입니까?

기본 데이터 세그먼트 (DS)를 넘어서 데이터에 액세스하기 만하면됩니다. ES와 똑같습니다.


긴 읽기 :

그래서 다음 레지스터와 그 용도가 무엇인지 알고 있습니다.

[...]

글쎄, 거의 DS는 '일부'데이터 세그먼트가 아니라 기본 데이터 세그먼트입니다. 기본적으로 모든 작업이 수행 되었습니까 (* 1). 이것은 기본적으로 databss. x86 코드가 다소 간결한 이유의 일부입니다. 가장 자주 액세스되는 모든 필수 데이터 (코드 및 스택 포함)는 16 비트 단축 거리 내에 있습니다.

ES는 64KiB의 DS를 초과하는 모든 것 (* 2)에 액세스하는 데 사용됩니다. 워드 프로세서의 텍스트, 스프레드 시트의 셀, 그래픽 프로그램의 그림 데이터 등과 같습니다. 흔히 가정하는 것과 달리이 데이터는 많이 액세스되지 않으므로 접두사가 필요한 것은 긴 주소 필드를 사용하는 것보다 덜 아프다.

유사하게 문자열 연산을 수행 할 때 DS와 ES를로드 (및 다시로드)해야 할 수있는 사소한 성가심 일뿐입니다. 이것은 적어도 당시 최고의 문자 처리 명령어 세트 중 하나에 의해 오프셋됩니다.

정말 아픈 것은 사용자 데이터가 64KiB를 초과하고 작업을 시작해야 할 때입니다. 일부 작업은 한 번에 하나의 데이터 항목에 대해 간단히 수행되지만 (생각해보십시오 A=A*2) 대부분의 경우 2 개 ( A=A*B) 또는 3 개의 데이터 항목 ( A=B*C)이 필요합니다. 이러한 항목이 다른 세그먼트에 있으면 ES가 작업 당 여러 번 다시로드되어 상당한 오버 헤드가 추가됩니다.

처음에는 8 비트 세계 (* 3)의 작은 프로그램과 똑같이 작은 데이터 세트를 사용하여 큰 문제는 아니었지만 곧 주요 성능 병목이되었습니다. 프로그래머 (및 컴파일러). 386을 통해 Intel은 마침내 두 개의 세그먼트를 더 추가하여 안심을 제공했습니다. 따라서 요소가 메모리에 분산 되어있는 모든 시리즈 단항 , 이진 또는 삼항 연산은 항상 ES를 다시로드하지 않고도 수행 할 수 있습니다.

프로그래밍 (적어도 어셈블리에서) 및 컴파일러 디자인의 경우 이것은 상당한 이득이었습니다. 물론 더 많을 수도 있었지만 3 개를 사용하면 기본적으로 병목이 없어 졌으므로 과도하게 사용할 필요가 없습니다.

현명하게 이름을 짓는 문자 F / G는 E 뒤의 알파벳 연속입니다. 적어도 CPU 설계 시점에서는 아무 관련이 없습니다.


* 1-단순히 두 개의 세그먼트 레지스터가 필요하므로 ES를 문자열 대상으로 사용하는 것은 예외입니다. 없이는 그다지 유용하지 않거나 항상 세그먼트 접두사가 필요합니다. 놀라운 기능 중 하나를 죽일 수 있습니다. (반복적이지 않은) 문자열 명령어를 사용하면 단일 바이트 인코딩으로 인해 최고의 성능을 얻을 수 있습니다.

* 2-돌이켜 보면 'Everything Else Segment'는 'Extra Segment'보다 이름을 더 잘 지정했을 것입니다.

* 3-8086 은 8800 이 완성 될 때까지 스톱 갭 측정 용으로 만 사용 되었으며 주로 임베디드 세계에서 8080/85 고객을 유지하기위한 것임을 기억하는 것이 항상 중요합니다 .


1
와,이 모든 것을 설명 해주셔서 감사합니다! 이것은 많은 것을 설명하고 매우 의미가 있습니다! +1
user541686
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.