스터디에서 푼 문제 중 기억하고 싶은 문제가 있어 연습문제 3.20 풀이를 기록하려고 한다.
define OP ___에서 밑줄친 곳에 어떤 연산자가 들어가야 하는지를 구하는 문제이다.

밑줄 안에 들어갈 연산자는 /이다.
어셈블리에 주석을 달아보면 아래와 같다.
// x in %rdi
arith:
1 leaq 15(%rdi), %rbx // rbx = 15 + x
2 testq %rdi, %rdi // 참고) x & x -> ZF = (x == 0) ? 1 : 0
// SF = (x < 0) ? 1 : 0
3 cmovns %rdi, %rbx // (SF == 0) ? (rbx = x) : rbx(x + 15와 동일)
// (SF는 결과가 음수이면 1, 아니면 0임)
4 sarq $4, %rbx // rbx = rbx >> 4
5 ret
rbx = 15 + x
x(%rdi)를 판단한다. x가 음수이면 SF는 1로, 0 혹은 양수이면 0으로 설정된다.
SF가 0이면(x가 0 혹은 양수이면) x가 되고, 1이면(x가 음수이면) rbx(x + 15와 동일)가 된다.
sar은 Arithmetic right shift로, rbx >> 4가 된다.
SAR k, D는 D = D >> k를 의미(Arithmetic right shift) - 밀 때 1이면 1 유지
SHR k, D는 D = D >> k를 의미(Logical right shift) - 밀 때 0 붙여서 미는 거
정리하면, 시프트하고자 하는 대상이 양수이면 >> 4를 하고, 음수이면 15를 더해서 >> 4를 한다. >> 4는 / 16과 비슷해 보이는데, 왜 음수이면 15를 더해서 >> 4를 하는 걸까?
>>는 양수/음수 관계없이 결과를 내림한다. /는 양수면 내림, 음수면 올림을 한다.>> 4의 결과를 내림이 아니라 올림으로 바꿔줘야 한다. (x / m)을 올림한 값 == ((x + m-1) / m)을 내림한 값과 같다. 예) x = -5일 때, 그냥 x >> 4를 하면 내림하여 -1이 된다. 하지만 x + 15 >> 4는 내림하여 0이 된다. 그리고 -5 / 16은 올림하여 0이 된다. 따라서 15를 더해서 >> 4를 한 값이 / 16을 한 값과 같은 것을 확인할 수 있다.
스터디를 하다가, 질문한 내용 중 정리하면 좋을 것 같은 문제여서 블로깅해보았다👍 틀린 내용이 있을 수 있지만 머릿속에 있던 내용을 한번 정리한다는 마음으로.. 혹시 틀린 부분이 있다면 댓글 등으로 알려주시면 정말 감사하겠습니다!