※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


앞서 굉장히 많은 Fact들을 나중에 배울 것이라며 그냥 무책임하게 넘겨버린 적이 있었다. 그 모든 것은 지금 이 순간에 Procedure Call을 통해서 설명을 한꺼번에 하기 위함이었다. 그리고 내 생각에 그 때 이 내용까지 전부 다 공부해버리면 머리 많이 아플 것이다.  아무튼 Procedure Call 공부를 시작해보자.


프로시저가 무엇일까? 위키피디아에서 말하기를


In computer programming, a subroutine is a sequence of program instructions that perform a specific task, packaged as a unit. This unit can then be used in programs wherever that particular task should be performed. Subprograms may be defined within programs, or separately in libraries that can be used by multiple programs.

In different programming languages a subroutine may be called a procedure, a function, a routine, a method, or a subprogram. 


이라고 한다. 즉, 서브루틴(sub routine)이 우리가 말하는 프로시저이다. 서브루틴, 함수, 프로시저 등등이 모두 같은 의미로 쓰인다고 한다. 굉장히 이해하기 쉽게 설명해 놨다고 생각한다. 어떤 특정 작업을 수행하기 위한 instruction들의 연속이라. 내 입장에서는 완벽한 정의라고 생각한다.


우리가 프로그램을 작성하다보면 여러가지 함수를 호출하곤 한다. 그 호출을 진행할 때 우리의 가상 메모리 상에서는 굉장히 많은 일들이 일어난다. 이 블로그의 어느 순간에도 말한 적이 있을 것이다. 스택을 사용하여 프로시저 콜이 구현된다고. 우선, 프로시저 콜을 이해하기 위해 자주 논의될 레지스터 세 개를 소개하겠다. %ebp, %esp, %eip 이다.


%ebp : 스택 프레임 포인터. 

%esp : 스택 포인터. 제일 Top을 가리킨다.

%eip : 프로그램 카운터, 즉 다음에 실행할 명령어의 주소를 가지고 있다.


스택 포인터는 어느 정도 이해할 수 있을 것이라고 믿는다. 그냥 스택의 Top을 가리키는 것이니까. 그렇다면 스택 프레임 포인터가 무엇인가? 스택 프레임이 무엇인지 먼저 설명을 해야한다. 그림으로 이해하면 편하다.




여러 칸의 집합이 하나의 스택 프레임이 된다. 저 스택 프레임 안에는 무엇이 있을까? 아직 궁금한게 많다. 차근 차근 설명을 따라오면 이해 가능할 것이라고 믿는다. 아무튼 지금은 이것만 알아두자. 위의 그림에서 색깔 별로 구분해둔 것 각각을 우리는 스택 프레임이라고 부를 것이고, 저것들을 하나하나가 함수들이다. 


가령, F1이라는 함수 내에서 F2라는 함수를 호출을 하면, 프로그램 흐름이 젤 처음에는 F1을 실행하다가 F2를 실행하고 다시 F1으로 돌아와서 F1의 실행 역시 끝나게 되는 것지? 그것이 결국 스택이다. F1이라는 스택 프레임이 쌓였다가. F2라는 스택 프레임이 Push되고 거기에서 모든 작업이 수행되면 F2라는 스택 프레임이 Pop되면서 다시 F1 스택 프레임이 스택의 Top을 가리키고 있는 것이다. 이제 조금 이해가 가리라고 믿는다. 


이제 스택 프레임이 무엇인지 알았으니, %esp %ebp 등이 스택에서 어떻게 존재하는 것인지 볼 것이다. 아래와 같다. 



즉 %ebp와 %esp가 가지는 값은 이렇다.

%ebp : 가장 Top에 있는 스택 프레임의 시작 주소

%esp : 그 스택 프레임 내에서의 가장 Top에 해당하는 주소


위와 같은 스택 구조에서 프로시저 콜은 다음과 같이 일어난다. 가령, Stack frame1이 메인함수에 대한 스택 프레임이라고 하고 Stack frame2는 sum함수에 대한 스택 프레임이라고 하자. 그리고 메인함수에서 sum함수를 호출한다고 하자. sum함수를 호출하기 전에는 다음과 같은 모습을 보일 것이다.



여기에서 sum함수를 호출하게 되면 다음과 같아진다.



sum함수가 모두 실행되고 main함수로 리턴되면 다시 이전의 스택 프레임 모습으로 돌아가게 된다.



이렇게 된다. 즉, 함수 호출을 끝내면 이전의 모습으로 돌아오게 되는 것이다.


이제 기본적인 것은 전부 설명했으니 본격적으로 Procedure Call을 공부해볼까나?

다음의 C코드를 보자.



이 코드에 대한 어셈블리어는 다음과 같다. 다음의 어셈블리어는 Fedora 16에서 실제로 컴파일



push? pop? leave? ret? 처음 보는 명령어들도 많이 있는데 차근 차근 공부해보도록 하자.


우선, 젤 처음에는 push 명령어를 수행하는데, 자료구조의 스택을 공부해본 사람은 알겠지만 push는 스택을 한 칸 늘리는 명령어이다. 물론 이 스택은 가상 메모리 상에 있다는 것은 다들 알고 있겠지? 모르겠다면 앞의 포스팅을 복습복습 해보자.


아무튼 젤 처음에 push1    %ebp명령어를 수행하면 다음과 같은 결과를 갖게 된다.

(얼마전에 42만원이라는 거금을 주고 iPad-mini를 구매했는데, 대만족이다. 필기 어플 유패드와 같이 사용하니까 내가 원하는 딱 그 용도로 너무 만족하며 사용하고 있다.)

※ 명령어를 수행하여 변하는 부분은 빨간 글씨로 해놨으니까 참고하세용!! 


위의 그림에서 보이듯이 push    %ebp 명령은 다음의 두 명령어와 동등한 효과를 낸다.

subl        $4, %esp

movl        %ebp, (%esp)

esp 값을 한칸 내려서 새로운 칸을 만들고 그 칸에 %ebp값을 집어 넣는것이다. 이것을 왜 할까? 저 부분이 바로 나중에 main함수의 이전의 스택 프레임으로 돌아가기 위한 방법이다. 애초에 %esp에 저장하는 그 값이 %ebp값인데, 이 값은 main 함수 이전 프로시저의 스택 프레임의 가장 밑을 가리키고 있다. 따라서 이 %ebp값을 main 함수에 대한 스택의 가장 밑에 집어넣어두면 나중에 언제든지 돌아가고 싶을 때 돌아갈 수 있다는 뜻이다.


다음 명령어를 보자.



이 명령어는 왜 했는지 조금 추측할 수 있어야 한다. ebp가 새로운 스택 프레임(main 함수)의 밑을 가리키네? 즉, 메인함수 스택 프레임의 bottom을 가리키면서 자연스럽게 스택 프레임을 이동한 것이다. 



위의 두 명령어는 도대체 왜 실행했는지 이유를 모르겠다;; 왜 했을까? 첫번째 andl 명령어 같은 경우 %esp의 값의 마지막 한 비트를 무조건 0으로 세팅해주는 효과를 낸다. 즉 이전의 %esp값보다 몇 칸 더 스택을 쌓는 꼴이 된다. 두번째는 몇 칸 더 쌓인 그 스텍 프레임에서 또 다시 스택 8칸을 더 할당시킨다. 왜 그럴까? 모르겠다;; 

(엇;; 위의 그림 보니까 subl    $32, %esp인데 오타가 났나보네;;;;ㅠㅠ)


아무튼 모르는 것은 일단 제껴두고 그 다음을 보자.

이 부분도 그림이 조금 잘못 됐다. %esp + 20을 하면 0x120C이다. 따라서 0x120C부터 0과 1이 쌓이기 시작해야한다. 그런데 이 부분이 조금 넌센스이다. 원래 일반적으로 책에서 배우기로는 old %ebp(0x1240)값 그 다음에 바로 0과 1같은 변수들이 쌓이기 시작해야 하는데 왜 이거는 이렇게 되는거지? 우선 이 부분도 넘어가자..ㅠㅠ




위의 과정은 쉽게 이해할 수 있어야 한다. 이 과정은 왜 하는가? 그 다음에 바로 sum 함수를 호출할 예정이기 때문이다. sum 함수는 0과 1을 파라미터 값으로 갖는다. 즉 sum함수에서 0과 1을 사용할 수 있어야 하겠지? 그러면 sum함수가 다가가기 쉬운 어떤 곳에 0과 1이 저장되어 있어야 하겠지? 바로 그것 때문에 여기에 저장해두는 것이다. 여기에 저장해두면 sum 함수 스택에서 여기를 찾기가 쉽나? 쉽다! 다음 명령어 그 다음 명령어를 보면 이해가 갈 것이다.


자... call sum 명령어이다. 이 명령어는 다음의 세 명령어 효과를 나타낸다.

subl        $4, %esp 

movl       %eip, (%esp)

jmp         sum

%esp값에 4를 빼서 한 칸을 더 확보한 후, %eip값, 즉 pc값을 %esp값이 가리키는 곳으로 집어 넣는다. 이유인 즉 이러하다. 



pc값을 스택에 집어넣어놔야 나중에 sum 함수 부분에서 다시 main 함수 부분으로 돌아올 수 있다는 것이다. 위 그림에서 옆의 숫자는... 지금은 보기 쉽게 line 수로 되어있지만, 실제로 저 부분은 0x08384330과 같은 pc값이 들어간다. 즉, 각각의 명령어는 그에 대한 pc값이 있다. call 명령어를 통해 sum함수의 push 명령어 쪽으로 점프를 한 것뿐이다. 아까 %ebp 저장하고 한 것은 뭐냐고? 그거랑은 조금 다른 얘기다. 이것은 코드 영역 이야기이고 아까 노란 종이에 계속 그려가면서 설명했던 것은 스택 이야기이다. 두 개가 다른 이야기이니 혼동하지 말도록 하자.


아무튼 그 다음 스택의 모습은 이렇게 된다.



이제 sum함수에 대한 스택 프레임이 생겼다. 여기에서 수행하는 명령어는 이전에 수행했던 그 명령어들과 같으니까 추가적인 설명은 생략하겠다.



그 다음이 또 중요하다 12(%ebp)값이 무엇인지 보자. 1이다. 저 부분은 사실 main 함수의 스택 프레임 영역인데 연산을 통해서 그 영역을 침범하여 파라미터 값을 가지고 오고 있다. sum 함수가 0과 1이 필요하잖아. 그 값을 어디서 가져와야 한다 그렇지? 그걸 main 스택 프레임의 pc값 위에서 가져오는 것이다. 첫번째 파라미터부터 차례대로 쌓여있으니까 %ebp값을 기준으로 +8은 첫번째 파라미터 +12는 두번째 파라미터 +16은 세번째 파라미터 이런식으로 가게 된다.


위의 그림에서 수행한 movl명령어와 addl 명령은 간단한 명령이므로 따로 설명은 하지 않고 넘어가자. 



pop명령어는 다음의 두 명령어와 같은 뜻이다.

movl        (%esp), %ebp

addl        $4, %esp

이는 스택의 Top에 있는 값을 %ebp에 저장한 후 스택 Top을 가리키는 레지스터인 %esp값에 4를 더하여 스택을 감소시키라는 뜻이다.



ret명령어는 위의 두 명령어와 같다. pop명령어를 통해 %eip(pc값)이 복원되었고, 그 값으로 jump하는 것이다. 



그러면 이제 다시 main 함수로 돌아가서 나머지 명령어 들을 수행하면 된다. 


간단한 예제인데도 그것에 대한 프로시저 콜을 공부하려고 하니까 아우... 골치가 아프다.

그래도 난 이게 재밌다. 재밌다. 재밌다. 


다음에는 프로그램의 효율성을 높여보는 공부를 해보자. 지금보다는 훨씬 재밌어 질 것이다. 어떻게 효율성을 높이냐고? 이러한 어셈블리어를 이해하면 효율성을 높일 수 있는 방법이 있다. 그 방법을 공부해보자. 실제로 그러한 방법을 통해서 30초 정도 걸리는 프로그램을 1초 이내로 성능을 향상시킬 수 있다. 다음 포스팅에 뵐께요!!


p.s. 혹시라도 윗부분에 제가 설명을 말끔하게 못 해둔 부분.. 그 부분에 대해서 정답을 아시는 분이 있다면 뎃글 부탁드립니다. 뎃글 주시면 아주아주 감사하겠씁니다ㅋㅋ

'System Programming' 카테고리의 다른 글

[SP] Conditional Jump  (1) 2013.05.14
[SP] Conditional Jump (Basic)  (0) 2013.05.14
[SP] Procedure Call  (0) 2013.05.04
[SP] Assembly Language Example  (0) 2013.04.30
[SP] Assembly Language  (1) 2013.04.30
[SP] Assembly Language Basic  (0) 2013.04.29
Posted by 빛나유

댓글을 달아 주세요

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


이전의 포스팅에서 어셈블리언어의 명령어들이 어떤 것들이 있는지 살펴보았다. 물론 그 외에도 무지하게 많은 명령어들이 있으나 다른 명령어들에 대해서는 앞으로 나올때마다 소개하는 식으로 하겠다.


자 그러면 하나의 예제를 통해서 이해해보자.



이와 같은 C 파일이 있다고 했을 때, 이것을 어셈블리 언어로 바꿔보자.



보아하니 .cfi_endproc 등등 처음 본 것들도 막 보인다. 깔끔하게 무시해주자. 저것은 나도 모르겠다. 하나 중요한 것은 저걸 지워도 프로그램은 잘 돌아가더라는 것이다. 저것이 무엇인지는 나중에 같이 공부해보자.


또 하나 우리가 스킵하고 넘어가야 하는 부분이 있다. 위의 세 줄과 밑의 두 줄이다.


pushl       %ebp

movl        %esp, %ebp

subl        $16, %esp


leave

ret


이 부분은 나중에 procedure call을 공부할 때 공부하는 부분이다. 지금은 그냥 한 함수의 시작과 끝을 표시해주는 것이라고만 생각하자.


## movl        8(%ebp), %edx

M[ %ebp + 8 ] 값을 %edx에 복사하라는 뜻이다. 그렇다면 %ebp에는 무엇이며 그것의 8칸 위에는 뭐가 있냐? %ebp 란 스택 프레임만을 가리키는 특별한 목적을 지닌 레지스터이다. 말이 어려워진다. 그냥 %ebp라는 어떤 기준이 되는 것이 있다고만 알자. 나중에 전부 Procedure Call에서 자세하게 다룰 것이다. 그러면 %ebp + 8에는 뭐가 있냐? swap(int* xp, int y)함수의 첫번째 파라미터 즉, xp의 값이 들어온다. xp는 포인터 값이므로 결국 M[ %ebp + 8 ]가 가리키는 값은 어떤 값을 가리키고 있는 주소값이 되겠다. 아래의 그림과 같다.

아직은 %ebp가 뭔지는 잘 모르겠지만 그 값이 아무튼 0x8048038이다.

movl        8(%ebp), %edx 명령어는 %ebp + 8 인 0x8048040의 값, 즉 0x8048010을 %edx에 저장하라는 뜻이다. 따라서 다음의 결과가 된다. 결국 xp라는 메모리 값을 레지스터에 저장해둔 것이다.




## movl        (%edx), %eax

xp가 가리키는 값을 255(0xFF)라고 가정하고 이야기 해보자.

이 명령어는 위의 명령어보다 조금 더 이해하기가 쉬울 거라고 생각한다 %edx가 가리키는 값인(0x000000FF)를 %eax에 저장하라는 뜻이다. 왜 %edx가 가리키는 값이 0x00이 아니고 0x000000FF인가? int 형은 몇 바이트인가? 4바이트이다. 그런데 위의 메모리 한 칸은 1바이트이다. 따라서 0x8048010에서부터 0x804800D까지 네 칸을 할당해서 사용해야한다.

이 명령어는 결국 xp가 가리키고 있는 255를 레지스터에 저장해두는 것과 같은 역할을 한다. 결과는 다음과 같아진다.



여기서 한가지 중요한 이야기를 하고 가자. 함수의 return 값은 항상 %eax에 저장된다. 위의 C코드를 다시 한번 보면, 이 함수의 return 값은 애초에 xp가 가리키고 있었던 정수(0xFF)이다. 따라서 0xFF가 %eax에 저장되는 것이다.


## movl        12(%ebp), %ecx

(swap 함수를 호출할 때 두번째 파라미터인 y에는 0이 있다고 가정하자.)

위에서 M[ %ebp + 8 ]에는 swap(int* xp, int y)의 첫번째 파라미터가 들어있다고 했다. 같은 원리로 두번째 파라미터는 12(%ebp)에 존재하게 된다. 그렇다. 함수의 파라미터들은 항상 %ebp값을 기준으로 +8칸 부터 그 위로 쭉쭉 쌓여나간다. +4칸에는 뭐가 있는가? 그것은 나중에 자세하게 이야기할 것이니 지금은 신경쓰지 말도록 하자.

아무튼 이 명령어의 결과는 아래와 같은 그림이 될 것이다.



M[ %ebp + 12 ]의 값을 %ecx 에 복사하는 것이다. 왜 0x8048044 로부터 네 칸이냐고? 위에서 다 설명했다.-_- 결국 이 명령어는 int y 값을 레지스터에 저장하는 명령어이다.


## movl        %ecx, (%edx)

이 명령어는 간단하다. %ecx값 0x00000000를 %edx가 가리키는 값에 집어넣는 것이다. 따라서 아래와 같은 결과가 나온다.



결국 이 명령어는 xp가 가리키는 값을 y값으로 변경시키는 것이다.


정리해보면 다음과 같다.


간단하게 예제를 통해 어셈블리 명령어를 이해해봤으니 다음 포스팅에서는 중요한 아주 중요한 push 명령어와 pop 명령어에 대해서 이야기 해보도록 하자. 이는 procedure call을 이해하는데 있어서 매우 중요한 사전 지식이 된다.


※ 앞으로 메모리칸을 그릴 때는 1바이트 단위로 자세하게 그리지 않고 4바이트 단위로 끊어서 그릴 생각이다. 혼동하지 않길 바란다. 그것이 조금 더 이해하기 쉬울 것이라고 믿는다.

'System Programming' 카테고리의 다른 글

[SP] Conditional Jump (Basic)  (0) 2013.05.14
[SP] Procedure Call  (0) 2013.05.04
[SP] Assembly Language Example  (0) 2013.04.30
[SP] Assembly Language  (1) 2013.04.30
[SP] Assembly Language Basic  (0) 2013.04.29
[SP] Purpose for Virtual Memory  (0) 2013.04.29
Posted by 빛나유

댓글을 달아 주세요

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


이번 포스팅에서는 레지스터와 메모리를 통해 어떻게 데이터를 표현하는지부터 실제로 어셈블리언어에 존재하는 명령어들을 공부할 예정이다. 


명령어를 통해서 연산을 하다보면 사용할 데이터들이 메모리에 있을 때도 있고 레지스터에 있을 때도 있을 것이다. 각각의 경우, 어떤 식으로 접근하는지 살펴보자.


레지스터에 접근하는 방법은 매우 간단하다. 그냥 해당 레지스터의 이름을 써주면 된다. 가령


add        %eax, %ebx

이와 같은 명령어가 있다면, %eax에 있는 값을 %ebx의 값과 더해서 %ebx에 저장하라는 명령어가 된다. 레지스터의 값에 접근하는 것은 이와 같이 매우 쉽다. 그냥 적기만 하면 되니까. 그렇다면 메모리의 값들은 레지스터를 통해서 어떻게 접근할까?


정답은 괄호를 통해서 접근할 수 있다. 가령 다음과 같이 예를 들어보자.


add        (%ebx), %eax


위의 명령어는 다음과 같은 뜻이다. %ebx가 가리키는 값에 %eax값을 더해서 %eax에 저장하라는 뜻이다. 따라서 %ebx 자체에는 가상메모리 주소 값이 저장되어 있다는 뜻이 된다. 어려운가? 그림으로 설명해보겠다. 다음과 같다.



결국 포인터 개념이다. %ebx에 주소값이 저장되어있어서 %ebx가 가리키는 곳의 값을 쓰겠다는 것이다. 이 add 명령의 결과는 11이 된다. %ebx가 가리키는 주소가 가지고 있는 값이 8이고 %eax가 가지고 있는 값이 3이고, 그 두 개를 더해서 %eax에 더해주는 것이니까 %eax는 11로 업데이트 된다. 


다음과 같이 괄호를 쓸 수도 있다.



M[ %eax + %ebx ]는 주소값 %eax + %ebx 이 가리키는 값을 의미한다. 또한 괄호에서 3번째 인자 값이 있다면 그것은 두번째 인자값에 곱하라는 뜻이다. 헛깔리지 말아야할 것 중에 하나가 $Imm와 Imm의 차이이다. (Imm는 변수가 아닌 상수를 의미한다. 즉, 변하지 않는 고정젹인 숫자를 의미한다.) $가 붙으면 일반 상수를 의미하지만, 없으면 그 값이 가리키는 메모리 값이 된다. 헛깔리지 말도록 하자.


이제 본격적으로 실제 어셈블리 언어에 대해서 이야기 해보자.

먼저 data movement를 위한 명령어로 mov가 있다. 하지만 실제로는 mov가 아닌 movl과 같이 뒤에 무언가가 붙어서 사용되곤 한다. 그 의미는 무엇일까? 바로 다루는 데이터의 크기를 의미한다.



밑에 보면 push 또는 popl 명령어도 있는데 이는 그냥 무시하자. 나중에 매우 자세하게 공부할 예정이다. 위의 명령어에서 가장 자주 쓰이는 것은 아무레도 movl이 아닐까 싶다. 기본적으로 word 사이즈의 데이터를 가장 많이 사용하지 않을까? 그렇기 위해서는 당연히 movl 명령어를 사용해야한다. 


그림의 왼쪽을 자세히 봐보자. MOV    S, D라고 되어있다. source와 destination을 의미한다. 출발지와 도착지. 즉, 출발지에 해당하는 데이터의 값을 도착지에 복사하라는 뜻이다. 따라서 도착지에 해당하는 값이 업데이트가 된다는 뜻이다. 


※ 프로그래밍 언어도 여러 가지가 있듯이, 어셈블리언어도 종류가 여러 가지가 있다. MIPS Architecture 같은 어셈블리언어에서는 출발지와 도착지가 반대이다. 매우 혼동될 여지가 있으니 조심하기 바란다. 이 블로그에서는 특별한 이야기가 없다면 무조건 도착지가 뒤에 온다.


이제는 산술연산 명령어를 살펴보기로 하자. 



우선 leal 명령어를 살펴보자. leal 명령어는 mov명령어와 헛까릴수 있으니 조심해야 한다. 예를 들어 설명하는게 젤 빠를 것 같다.


위와 같은 상태에서 아래의 명령어의 차이를 이해해보자.


leal        (%ebx), %eax

movl       (%ebx), %eax


movl       (%ebx), %eax는 %ebx가 가리키는 값(8)을 %eax에 복사하기 때문에 %eax의 값은 8로 업데이트 된다. 

반면, 

leal        (%ebx), %eax는 그냥 %ebx의 값이 %eax에 복사되기 때문에 %eax의 값은 0x8048040으로 업데이트 된다.


leal 명령어의 이러한 특성 때문에 leal 명령어는 실제로 산술연산을 효율적으로 끝내버리는데 사용하기도 한다. %eax에 3이라는 값이 들어있을 때, 다음의 명령어를 보자.


leal        (%eax, %eax, 4), %ebx


이는 %eax의 값(3)을 5배 해서 %ebx에 저장하라는 명령어가 된다. leal 명령어의 특성상 %eax의 실제 값을 접근하기 때문에(%eax가 가리키는 값이 아닌) 


%eax값 + %eax값*4 = %eax값 * 5


이와 같은 계산이 가능해지고 %eax가 3이기 때문에 결국 하나의 산술연산을 하게 된 샘이 된다. 왜 굳이 add 명령어나 imul 명령어를 사용하지 않는가? 왜 일까? 훨씬 빠르기 때문이다. 기본적으로 imul 명령어는 곱하기 명령어인데, CPU가 이 명령어를 실행하려면 몇 clock cycle을 소모한다. 반면 add명령어는 1 clock cycle을 소모하지만 5번이나 더해야 하기 때문에 결국 오래 걸리기는 매한가지이다. 반면 leal 명령어는 단 1 clock cycle에 끝낼 수 있다. 따라서 빠른 정수 연산이 가능해진다.


곱하기 5를 하는 연산은 다음과 같이 수행할 수 도 있다. C언어로 표현해보자.


x = x<<2 + x


이 값 역시 x에 곱하기 5를 한 셈이 된다. 왜냐하면 x<<2가 결국 x*4와 같기 때문이다. 이것이 이해가 안가면 2진수를 다시 공부하면 된다. <<k 는 k만큼 left shift 하라는 의미인데 한 칸 left shift하는 효과는 결국 그 숫자의 두배를 하라는 효과이기 때문에 2칸 left shift 하는 것은 4배 하라는 의미가 되기 때문이다. 거기에 원래의 x를 한번만 더 더해주면 결국 5*x가 되어버린다. 곱하기 명령어를 수행하면 몇 cycle이 걸리는 것을 shift 연산을 사용하면 2 clock cycle(shift가 한 cycle, add가 한 cycle) 만에 끝낼 수 있다. 즉 빠르다.


shift 연산을 통해 조금 더 빠른 곱셈 연산이 가능하다는 것 정도는 알아두자.


물론 leal 명령어를 통해 계산하는 것이 가장 빠르다. 실제로 요즘 컴파일러들은 level 01 optimization에서도 저 정도의 최적화는 수행한다고 한다.


나머지 add, sub, sal 등의 명령어는 그냥 각자 공부해보자. 저 위의 표만 잘 봐도 충분히 이해 가능하다고 생각해서 굳이 따로 설명하지는 않는다.


다음 포스팅에서는 지금까지 배운 명령어들을 예제를 통해서 활용하면서 공부해보도록 하자.

'System Programming' 카테고리의 다른 글

[SP] Procedure Call  (0) 2013.05.04
[SP] Assembly Language Example  (0) 2013.04.30
[SP] Assembly Language  (1) 2013.04.30
[SP] Assembly Language Basic  (0) 2013.04.29
[SP] Purpose for Virtual Memory  (0) 2013.04.29
[SP] Virtual Memory  (3) 2013.04.29
Posted by 빛나유

댓글을 달아 주세요

  1. 2017.04.26 20:19  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다