cs와 eip의 관계

jungwook의 이미지

안녕하세요? 만들면서 배우는 os 커널의 원리를 보고 있는데,
헷갈리는 부분이 있어서 글을 작성합니다.

먼저 EIP가 현재 실행될 명령어의 주소를 가지고 있는 레지스터잖아요.

그런데 책을 보다보니, CS에서 base address를 가져오고 EIP를 base address의 offset으로 사용하는 경우가 있더라고요.

TSS에도 cs가 저장되어있고, task switching이 일어나면 단순히 EIP만 읽으면 다시 실행될 위치에서 실행되는거 아닌가요??
cs를 저장하는 이유는 limit를 체크하기 위해서인가요??

흠.. ㅡㅡ;

헷갈리네요.

답변 부탁드립니다.

namhw의 이미지

제가 이해한 CS, DS와 같은 셀렉터 레지스터가 필요한 이유로는 단순히 주소지정을
위해서이기도 하지만 다양한 메모리 영역을 구분해주기 위해서 입니다. 기본적으로
사용자레벨과 커널레벨이 구분된 운영체제의 경우 각 영역의 CS에는 RPL 필드에
각 권한레벨을 명시하게 됩니다.

TSS에 CSS가 포함된 이유로는 책 244페이지 6번을 보시면 CS에 기입된 권한레벨을
체크하는 부분이 설명되어 있습니다. 이는 인터럽트와 같은 이벤트가 발생했을 때 현재의
태스크가 커널레벨일 경우와 사용자 레벨일 경우일 때의 처리 방법이 달라지게 됩니다.
자세한 내용은 책을...^^ 즉 TSS에 CS가 필요한 Base Address를 참조하기 위한
용도뿐 아니라 스케줄링할 곳이 어떠한 메모리 영역인지를 알기 위해서도 사용됩니다.
만약 EIP만 사용한다면 원하는 메모리 번지는 접근할 수 있겠지만 커널 레벨의 메모리
주소인지 사용자 레벨의 주소인지는 구분할 수 없겠죠.

촌놈.

촌놈.

jungwook의 이미지

답변 감사드립니다.

cs와 ds가 Previled level을 위해서도 사용되고,
또한 세그먼트의 Limit를 체크위해서도 사용되는 것 같네요.

여기서 하나 더 궁금한건

page 82 를 보면 DS 세그먼트 셀렉터에 값을 넣었을 때의 cpu의 동작이라는 그림이 있죠~
그걸 CS라 생각하면, gdtr과 세그먼트 셀렉터를 이용하여 먼저 base address를 찾고, 그 base address + offset(?) 을 이용하여
다음에 실행될 명령어를 가져오는거 같은데,
base address + offset = EIP 이런 공식이 성립하는 건가요?
이런 명령은 page 85에 나오는 메모리에 접근할 때만 생기는 거겠죠? base address + offset

CS에서는 이런 방식이 jmp 명령시에 발생하겠지요??

page 176 쪽의 세그먼트 셀렉터의 스위칭에서 헷갈리는거 같은데,
실제 태스크 스위칭은 EIP를 이용하여 다음번에 실행될 주소를 꺼내오고,
CS에 기록된 내용은 체크를 위해 사용하나보네요. ㅡㅡ;

실제 프로세서 내에서는 cs를 참조해서 base address 를 찾을 필요없고,
32bit cpu라면 EIP + 4라는 명령 (컴구 시간에 배운듯) 으로 instruction을 가져오겠죠?

좀 더 정리를 해야할 듯 ㅡㅡ;

SoulreaveR의 이미지

EIP를 이용할 때 CS 주소를 이용하는 것은 architecture의 정의에 따라 다릅니다. 대부분이 EIP + CS base address를 실행해야 할 instruction이 있는 주소로 사용하긴 하지만 그렇다고 반드시 그렇다고 하는 것은 안될 것 같습니다. 좀 오래된 문서이긴 하지만, intel 8086 instruction set manual에 보면 이런 내용이 있습니다.

By default, the DS (data segment) is used for data transfer instructions (e.g. MOV), CS (code segment) is used with control transfer instructions (e.g. JMP or CALL), and SS is used with the stack pointer (e.g. PUSH or to save/restore addresses during CALL/RET or INT instructions).

segment는 초기 multi process환경에서 각 프로세스들이 사용하는 메모리 공간을 구분하기 위해 개발되었습니다. 즉 프로세스를 위한 virtual memory를 생성하기 위함이었습니다. 이를 통해 각 프로세스는 자신의 base address가 무엇인지 알 필요없이 자신의 메모리 이미지 내에서 정확한 offset만 알면 되었습니다. 그 얘기는 바꿔 말해서 프로세스가 정확하게 동작하기 위해서는 자신의 메모리 위치를 올바르게 가리키는 segment register가 있어야 한다는 뜻입니다.(segment register를 사용하는 architecture라면)

하지만 paging과 비교했을때, virtual memory space를 제공한다는 점에서 매우 유사하기 때문에 최근에는 예전의 segment에 대한 개념을 전부 사용하는 os는 거의 없다고 봐도 무방합니다. (제가 알기로 full segment + paging을 다 사용하는 os는 IBM OS/x 계열밖에 없는 것으로 알고 있습니다.) 간단하게 아무 리눅스에서 어떤 프로세스든 gdb를 통해 실행하시고 info reg를 하시면 cs, ds, ss등이 모든 프로세스가 같은 값을 가지고 있다는 것을 확인하실 수 있습니다 - kernel은 다릅니다. 위에 분이 답하신것처럼, 권한 field 값이 다르기 때문에 kernel의 cs / ds는 다른 값을 가집니다. 이 부분은 linux segmentation을 검색해 보시면 좀 더 자세한 답을 얻으실 수 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.