인텔 32비트 CPU에서 조건부 분기 없이 32비트 정수의 절대값 구하기는 이미 잘 알려진 코드다. 32비트 운영체제가 대세가 되면서 한동안 어셈블리 코딩을 하지 않던 나에게 다시 인텔 어셈블리어 코딩을 하도록 끌어들인 그 코드. 조건부 분기하는 것보다 빠른 것은 물론 더 짧다.
; 입력: eax = 절대값을 구할 정수 ; 출력: eax = 입력값의 절대값 ; 기타 사용 레지스터: edx cdq xor eax,edx sub eax,edx
초보를 위한 설명:
CDQ
명령으로 EAX 레지스터의 부호를 EDX로 복사하면, EDX는 -1이거나 0이다.XOR
연산을 0에 대해 하면, 바뀌는 것 없다. 2의 보수로 표현한 -1에 대해 하면NOT
연산과 같다.SUB
명령에 인수로 0을 주면, 바뀌는 것 없다. -1을 주면INC
명령과 같다.
NOT
연산뒤 1 증가시키니까, 2의 보수로 음수를
표현하는 인텔 CPU에서는 NEG
명령과 같은 결과를 얻는다.
어느정도 인텔 어셈블리 코딩을 해온 사람이라면 이 코드를 하도 많이 써서 관용구로 외우고 있을 것이다.
매크로로 만들어 놓은 사람도 분명 있을 것이고... 게다가, 앞뒤로 한줄씩만 더하면 바로 C표준함수
labs()
이다. 물론, 이 코드를 내가 본 것이 벌써 10년전이니까, 요즘 컴파일러들은
labs()
를 이렇게 바로 인라인할 것이라고 추측된다.
누군가 어셈블리어를 검색해서 찾아온 것을 보고 나서 32비트 초보 시절의 기억을 되새겨 보았다.