정의
ROL = Rotate Left ; 어셈블리에서 왼쪽으로 shift해주는 연산
ROR = Rotate Right ; 어셈블리에서 오른쪽으로 shift 해주는 연산
일반적인 shift 연산
일반적인 shift 연산에서, 최상위 비트를 MSB, 최하위 비트를 LSB라고 한다.
MSB = Most Significant Bit
LSB = Least Significant Bit
LEFT SHIFT 연산)
왼쪽으로 shift 연산 시, MSB가 왼쪽으로 밀리면서 LSB에 0을 추가한다.
* 따라서 이 경우 부호 bit에 영향을 주지 않는다
e.g.
1011 1011 을 왼쪽으로 1 번 shift 한다면
=> 10111 0110
=> 0111 0110
첫 번째 과정의 가장 왼쪽의 1이 CF (Carry Flag)인데,
이 경우 대부분의 컴퓨터 아키텍쳐에서 왼쪽으로 shift할 때 CF는 그냥 버려진다.
따라서 왼쪽으로 shift하면 MSB는 CF에 영향을 주지 않는다
RIGHT SHIFT 연산)
오른쪽으로 shift연산 시, LSB가 오른쪽으로 밀면서
MSB == 1 (음수) 인 경우 1로 채워짐
MSB == 0 (양수)인 경우 0으로 채워짐
=> 부호가 있는 정수의 부호를 유지하면서 shift연산을 할 수 있다.
e.g.
1011 1011을 오른쪽으로 1번 shift한다면
=> 1101 11011
=> 1101 1101
가장 오른쪽의 밀려난 1 (CF)이 버려진다.
ROR, ROL
Rotate라는 단어가 쓰인 이유가 있다
=> 일반적인 SHIFT 연산의 경우, CF가 그냥 버려지지만
ROR, ROL의 경우 CF가 각각 가장 왼쪽 / 가장 오른쪽으로 옮겨져 빈 bit를 채워주게 된다.
shift 연산과 비슷하지만, CF의 처리 방법, 빈 bit에 채워넣는 bit의 성격이 다르다
shift 연산의 경우
=> CF를 그냥 버리고,
=> 왼쪽 shift에서는 LSB에 0을 채워넣기 / 오른쪽 shift에서는 MSB 한번 더 써주기
의 방법을 선택하지만
ROR, ROL의 경우
=> CF를 그냥 버리지 않고
=> 빈 bit에 CF를 다시 채워넣는 방법을 선택한다.
진짜 그냥 Rotate : 회전하는거다~
넘친 부분을 빈 부분에 채워넣고 이러는 방식으로
ROR, ROL 코드 (C)
ROR)
int ror(int x, int n) {
int shift = x >> n; // (a)
int src = x << (8-n); // (b)
src &= 255; // (c)
return shift | src; // (d)
}
ror 함수는 int형 변수 x, n을 파라미터로 받는다.
이때 x는 shift가 일어날 비트이고, n은 shift 횟수이다.
(a) : shift 변수를 선언하고, shift 변수에는 x를 오른쪽으로 n만큼 shift한 결과를 담는다.
이때 shift하면 CF가 버려지기 때문에, CF를 저장할 다른 변수도 필요할 것이다
(b) : src 변수를 선언하고, src 변수에는 shift 변수 선언 시 shift 연산을 하며 버려진 CF들을 담는다.
(c) : src 변수에서 x를 왼쪽으로 밀었기 때문에 x의 오른쪽 (8-n)만큼의 bit는 0으로 채워진다.
또한 x의 오른쪽에는 밀린 bit들이 있는데, 걔들을 제거하기 위해 255, 즉 1111 1111 과 &연산을 해서
왼쪽으로 오버플로우된 bit들을 0으로 만든다.
e.g.
ror (1011 1011, 1)이라면
shift에는 0000 0000 0101 1101이 저장될 것이고,
src에는 0101 1101 1000 0000이 저장될 것이다.
우리가 src를 만든 것은 CF를 저장하기 위함이었으므로 사실상 하위 8bit, 즉 1000 0000만 필요하기 때문에
앞의 8bit인 0101 1101을 지우기 위해
255 (10진수) = 0000 0000 1111 1111과 &연산을 해서 src의 앞 8bit를 지워주고, 하위 8bit는 그대로 유지하는 것이다.
그렇게 하면 src에는 0000 0000 1000 0000만 저장된다.
(d) : shift와 src를 OR 연산한 결과를 반환한다
e.g.
shift = 0101 1101
src = 1000 0000
-------------------------
OR = 1101 1101
ROL)
int rol(int x, int n) {
int shift = x << n;
int src = x >> (8-n);
shift &= 255;
return shift | src;
}
ROL의 경우, shift할 때 왼쪽으로 옮겨서 부호 bit에 영향을 줄 수 있게 되므로
shift 변수에 저장되는 수를 255와 &&연산해서 하위 8bit만 남을 수 있게 한다!!
'étude > reverse engineering' 카테고리의 다른 글
dreamhack : rev-basic-5 (0) | 2023.11.05 |
---|---|
dreamhack : rev-basic-6 (0) | 2023.11.05 |
dreamhack : rev_basic_7 (1) | 2023.11.04 |
dreamhack : rev_basic_3 (2) | 2023.08.06 |
dreamhack : rev_basic_2 (1) | 2023.08.05 |