TIL 10월 30일 2023년

ORCASUIT·2023년 10월 30일
0

Zero-extendingSign-extending은 작은 크기의 데이터를 더 큰 크기의 레지스터로 복사할 때 사용하는 방법입니다. 두 방법 모두 데이터를 소스에서 대상으로 복사하는데 사용되지만, 빈 공간을 채우는 방식이 다릅니다.

  1. Zero-extending (movz class):

    • 복사된 데이터 외의 나머지 바이트를 0으로 채웁니다.
    • 예: movzbw는 바이트(byte)를 워드(word, 2바이트)로 확장할 때 사용되며, 복사된 바이트 외의 바이트는 0으로 채워집니다.
  2. Sign-extending (movs class):

    • 복사된 데이터의 최상위 비트(MSB, Most Significant Bit)를 사용하여 나머지 바이트를 채웁니다.
    • 예: 어떤 바이트 값의 MSB가 1(음수)인 경우, movsbw를 사용하여 워드로 확장할 때 나머지 바이트도 1로 채워집니다.

각 명령어의 이름 뒤에 있는 두 문자는 소스와 대상의 크기를 나타냅니다. 예를 들어, movzbw에서 b는 바이트(byte)를, w는 워드(word)를 나타냅니다.

이러한 확장 명령어는 주로 작은 데이터 타입에서 큰 데이터 타입으로 변환할 때 사용됩니다. 변환하는 동안 데이터의 원래 의미를 유지하기 위해 위와 같은 확장 방법이 필요합니다.


각 레지스터의 접미사는 해당 레지스터의 크기를 나타냅니다:

  • b: 바이트 (1 바이트)
  • w: 워드 (2 바이트)
  • l: 더블 워드 (4 바이트)
  • q: 쿼드 워드 (8 바이트)

이를 기반으로 각 명령의 접미사를 결정할 수 있습니다:

  1. mov__ %eax, (%rsp)

    • %eax는 더블 워드 크기의 레지스터입니다.
    • 결과: movl
  2. mov__ (%rax), %dx

    • %dx는 워드 크기의 레지스터입니다.
    • 결과: movw
  3. mov__ $0xFF, %bl

    • %bl는 바이트 크기의 레지스터입니다.
    • 결과: movb
  4. mov__ (%rsp,%rdx,4), %dl

    • %dl는 바이트 크기의 레지스터입니다.
    • 결과: movb
  5. mov__ (%rdx), %rax

    • %rax는 쿼드 워드 크기의 레지스터입니다.
    • 결과: movq
  6. mov__ %dx, (%rax)

    • %dx는 워드 크기의 레지스터입니다.
    • 결과: movw

이로써 각 명령어에 대한 올바른 접미사를 결정할 수 있습니다.

Q. 3번에서 $0xFF의 크기를 고려하지 않고 %bl의 크기를 고려하는 이유는 뭔가요?

좋은 질문입니다. x86 어셈블리에서 mov 명령어의 경우 대상 레지스터의 크기가 주어진 데이터를 이동시키는 데 사용됩니다. mov의 경우 소스 데이터의 크기는 무시되며 대상 레지스터의 크기만 고려됩니다.

3번 예제에서 $0xFF는 1바이트 값을 나타냅니다. 그러나 실제로 이 값을 2바이트 레지스터 또는 4바이트 레지스터에 이동할 수도 있습니다. 그래서 실제로 어떤 레지스터로 데이터가 이동되는지 확인하여 접미사를 결정합니다. 여기서 %bl는 바이트 크기의 레지스터이므로, movb를 사용합니다.

이러한 방식으로 mov 명령어는 소스 데이터의 크기를 알 필요 없이 대상 레지스터의 크기에 따라 데이터를 이동시킬 수 있습니다.

0개의 댓글