Machine-Level Representation of Programs: Arithmetic Operations(5)

G·2022년 10월 13일
0

2-2 System programming

목록 보기
3/15

Arithmetic Operations

Week 7-1에서 배운 mov instructor는 operands(피연산자)를 중심으로 바라보았다. 이번 시간엔 타입이 다른 operands에 따른 operation의 변화와 다른 종류의 opertion을 살표본다.
예를 들어, long type varname = integer type value 이런식의 형변환이 일어났을 때의 register의 값이 변화되는 과정과 다른 종류의 instructor를 알아본다.

Data size

밑은 Operation에서의 data size를 의미한다.
이들은 연산에 영향을 끼치며 mov와 같은 연산에 명시적으로 붙어 ex). movbw(b레지스터의 값이 w의 레지스터로 복사된다.)
값 대입시 내부적으로 레지스터가 어떻게 작동하는지 확인할 수 있다.

  • A byte: 1 byte b
  • A word: 2 bytes w
  • A double word: 4 bytes l
  • A quad word: 8 bytes q

    위의 표를 보면 r로 시작하는 레지스터는 64 bit이므로 q이다.
    대부분의 e로 시작하는 레지스터는 l이다.
    나머지 w과 b는 수시로 확인해보자.

    4: b, 5: q, 6: w
    위의 이미지에서 알 수 있는 사실은 src와 dst를 모두 비교해야한다.
    어떤 상수을 8bytes에 옮긴다면 8bytes의 형태로 만들어줘야한다. signed형태면 0이나 1을 앞에 전부 붙여주면 된다. 만약 1 byte의 값을 메모리 영역에 복사할 땐 1 byte 형태만 복사하면 된다. dst가 메모리면 입력값을 확인하면 되고(1 byte의 경우 movb) dst가 레지스터면 src의 값이 dst의 형태(레지스터가 8bytes면 movq)로 복사되면 된다.


위의 이미지를 확인해보자.
1번은 8bytes의 값을 그대로 8bytes인 %rax에 복사해 문제없이 복사된다.(movabsq는 absolute quad word를 quad word dst로 복사할 때 사용한다.)
2번은 -1의 형태가 2 bytes 형태로 복사되기 때문에 1111 1111이 맨 오른쪽 2 bytes에 복사된다.
3을 보자. %eax는 l 즉 double word이다. 32 bytes에 -1을 저장하기 때문에 위와 동일한 방식으로 해결하면 되는데, movl은 예외적으로 상위 bit들을 모두 0으로 초기화한다. 이 점을 잘 알아두자.


(참고용)

movs and movz

지금까지 data 크기가 다른 copy가 이루어질 때 내부적으로 어떤 일이 생기는 지 알아보았다.
register가 32bit 이면 복사값을 32bit로 맞춰주면 되는 것이였다. 상위의 32bit는 수정되지 않고 복사되는 것도 확인하였다. %rax는 64bit인데 %eax는 32bit이니 32bit 공간 안에서만 복사된 값을 저장해주면 되는 것이였다. 그런데 만약 특정 수가 32bit로 저장이 되어있는데 이를 64bit 레지스터에 저장하려면 어떻게 해야할까? 그냥 movz라면 상위 bit를 모두 0으로 채우고 movs면 1로 채우면 된다.

예외로 아까 보았듯이 32bit를 64bit에 할당할 때 movl 자체가 상위 bit를 자동으로 0으로 초기화하는 것을 보았다. 그렇기 때문에 movzlq instructor는 존재하지 않는다.

Arithmetic Operations


산술 연산자들을 알아보자. 위의 내용은 참고하면 된다.
ADD 이전까진 모두 단항 연산자이고 ADD부터 이항 연산자이다.

lea

mov와 굉장히 유사한 lea instructor는 mov가 indirect addressing에서 메모리에 저장되어 있는 값이나 저장공간을 이용할 때, lea는 메모리 주소값 자체를 사용하여 복사한다.

mov의 경우 %rax 레지스터에 저장되어 있는 값의 메모리 주소이니, 이 주소가 가지고 있는 값을 사용한다. 거기에 6을 곱해 %rdx 레지스터에 저장한다.
그런데 lea 같은 경우 7 + %rax(레지스터에 저장되어 있는 값) + %rax * 8의 값 자체를 복사한다.

이후 4번 left shift를 하는 것을 볼 수 있다. 2^4을 곱해준다.

Unary Operations(단항 연산자)


src와 dst와의 연산을 통해 D에 저장해주는 형식이다.

  • INC: Increment
  • DEC: Decrement
  • NEG: Negate
  • NOT: Complement(2의 보수)

    rcx엔 0x1 값이 있고 이 값에 -1을 해주면 된다. 이값을 dst인 %rcx에 저장한다.
    0x10+0x100(%rax)는 0x110이다. 이 값은 메모리이므로 저장된 값에 연산을 한다.
    0x13 + 1 은 0x14이다.

Binary Operations(이항 연산자)


src와 dst값에 연산을 한 이후 dst에 저장한다.

예시(단항 연산자와 별 다를게 없다.)

profile
열심히 안 사는 사람

0개의 댓글