어셈에서 배열offset 계산하는 방법에 대한 질문입니다.
글쓴이: 이상훈 / 작성시간: 일, 2003/08/17 - 8:09오전
C코드로 배열을 선언하고 배열 내용을 읽는 간단한 코드입니다.
우선 배열은 아래처럼 선언했구요..
struct tTable{ char a; int b; int c; }; typedef struct tTable tTable; tTable Table[100][31];
코드를 어셈소스로 바꿨습니다.
아.. 어셈 소스로 바꿀 때 gcc를 썼습니다.
그런데 Table[i][j]에 있는 내용을 읽는데 어셈소스에서 offset을 아래처럼 구하더군요..
movl -8(%ebp), %ecx <- j 값입니다. movl 8(%ebp), %eax <- i 값입니다. movl %eax, %edx sall $1, %edx addl %eax, %edx movl %edx, %eax sall $5, %eax subl %edx, %eax <- 여기까지가 i*3*31 계산부분 이 됩니다. leal 0(,%eax,4), %edx movl %ecx, %eax sall $1, %eax addl %ecx, %eax sall $2, %eax <- 이 부분도 그냥 j*3을 써도 될것 같은데 말이죠... leal (%eax,%edx), %eax
그런데 이미 배열의 크기를 알고 있고 각 배열 노드의 크기도 알고있으니까 offset을 mul 를 사용해서 바로 구할 수 있을 것 같은데, 왜 굳이 저 방법으로 값을 계산하는 지 궁금합니다.
mul가 cycle이 더 걸린다고 해도 위에 나와있는 것보다는 적게 걸릴 것같은데 왜 mul를 사용하지 않았는지 정확한 이유를 알 수가 없네요 고수님들의 조언바랍니다.~-0-
Forums:
그 이유는
컴파일러 최적화 기교 중 하나입니다.
실제 mul을 반도체 로직 레벨에서 구현해보면
시간 오래 걸리게 되어 있습니다. 연산 과정도 상당히 복잡하고요.
(실제 알고 보면 나눗셈이 곱셈보다 더 복잡하긴 하지만)
이때문에 2,4,8 이런 식의 몇몇 상수값들을 곱하는 경우 곱셈이 아닌
쉬프트 연산으로 처리합니다.
쉽게 말하자면 우리 머리 속에서 어떤 숫자에 10을 곱할 경우 일일이
풀어서 계산하는 것이 아닌 원 숫자 뒤에 동그라미 하나 더 붙이는것과
같습니다. 100일 경우는 동그라미 두개, 1000을 곱하면 3개
Written By the Black Knight of Destruction
댓글 달기