어셈 질문(leal, sarl, shrl 등)
글쓴이: 시지프스 / 작성시간: 일, 2008/06/15 - 11:32오전
int c = -33; c /= 2;
를 gcc로 컴파일 했더니 다음과 같이 나왔습니다.
movl $-33, -4(%ebp) movl -4(%ebp), %edx movl %edx, %eax sarl $31, %eax shrl $31, %eax leal (%edx,%eax), %eax sarl %eax movl %eax, -4(%ebp)
0과 비교해서 음수면 1을 더하고 양수면 넘어가야 되는데, branch하는 게 싫어서 이렇게 한 것 같습니다만...
sarl $31, %eax
shrl $31, %eax
이렇게 하는 것은 그냥 shrl $31, %eax와 뭐가 다른가요? %eax가 양수면 0, 음수면 1을 남기려는 것 아닌가요?
그리고 leal이 무엇인지 궁금하네요.
조인시 위키에는
Quote:
eal M, I/R/M O/S/Z/A/C
다른 명령어들 처럼 특정 메모리 위치에 있는 값을 읽는 것이 아니라 메모리 주소를 읽어들이게 된다. 예를 들어 leal 5(%ebp, %ecx, 1), %eax는 5+%ebp+1*%ecx로 계산한 주소 값의 메모리를 읽어서 %eax에 저장한다.
라고 되어 있는데, 메모리에 저장된 것이 아무것도 없으니 이건 아닌 것 같고, 어셈 러브에 가보니 이런 글이 있는데, 여기서는 이렇다고 하네요.
Quote:
leal -4(%ebp), %eax // 이것은 이런 뜻임 movl $-4, %eax ; add %ebp, %eax
그런데
leal datablk, %ebx //이것은 이런 뜻임 void *ebx = (void *) &datablk;
아무튼 이것저것 읽어봤는데 전혀 이해가 안 되고 있습니다.
그리고 leal을 쓰는 것이 add를 쓰는 것보다 빠르다는 말이 있는데 그건 왜 그렇죠? add도 한 사이클이면 충분하지 않나요.
Forums:
int d; scanf("%d",&d); d /=
이런식으로 하고 최적화 옵션을 주니 결과가 달라지네요.
결론은 컴파일러 마음이군요.
아직 leal은 이해하지 못하고 있습니다. 설명 좀 해주세요.
begin{signature}
THIS IS SPARTA!!!!!n.
end{signature}
lea는 조금 특별한 최적화 방법입니다.
lea 명령은 해당 주소를 얻는 연산이기 때문에 레지스터를 이용하여 간접 주소로 접근할 때는 레지스터의 값을 계산한 결과와 동일하게 됩니다. lea를 사용하면 CPU의 주소 계산 기능을 이용하여 특수한 수에 대한 곱셈 및 덧셈을 할 수 있습니다. 그것도 곱셈 명령을 사용하지 않으면서 clock cycle도 적게 소모하고 pipeline의 효과도 볼 수 있기 때문에 i486 이후부터 널리 사용되었습니다.
예를 들어 eax = eax * 5라는 계산을 해야 한다면 leal (%eax, %eax, 4), %eax이라고 하면 됩니다. eax + eax * 4 == eax * 5이니까요.
그리고 위의 최적화는 나눗셈의 비용이 크기 때문에 곱셈과 shift 연산의 형태로 치환한 것으로 보입니다.
댓글 달기