Busan IT/Assembly2015. 10. 1. 17:41

==================================Outline====================================

확장, 반복문

- ECX 점검 명령어 jecxz

- 배열

- 주소 값 복사 명령어 lea

- Pipe의 개념 

Procedures

- 80X86 Stack

----------------------------------------------------------------------------

 

ECX 점검 명령어 jecxz

 

교재 p/175

 

loop문에서 ECX0일 경우 -1 연산이 적용되면 값이 FFFFFFFF되어 버린다.(loop문이 아주 오래 동안 실행된다.)

 

je endFor

 

때문에 ECX0인지 확인을 해주어야 한다. 이때 사용 되는 명령어가 jecxz이다.

 

컴파일러는 프로그래머가 작성한 코드를 효율적으로 기계어로 변환해준다. 현재의 컴파일러는 성능이 향상 되어서 어셈블러 지식이 애매한 프로그래머보다는 최적화된 코드를 제공해준다.

 

C는 컴파일을 거치게 되면 assembly language가 나오게 된다. C를 사용함으로써 기계어와 대응하는 어셈블리어가 나오기 때문에 C언어는 40년째 사용되고 있다.

 

배열

 

교재 p/180, 

 

배열은 프로그래밍에 많이 사용된다. 배열 사용을 지원해주는 명령어에 대해 알아보자.

 

배열 복사를 위한 레지스터

 

ESI(Extended Source Index)

EDS(Extended Dest. Index)

 

주소 값 복사 명령어 lea

 

lea 명령어는 주소 값을 레지스터에 담는 명령어이다.

 

ex) lea ebx, nbrArray

 

 

mov [ebx], eax ;register indirect, 포인터 개념

; &ebx = eax;

 

C에서는 변수의 주소를 1 증가 시키면 변수의 크기만큼 증가하게 되지만 어셈블리에서는 주소는 전부 1byte로 취급하기 때문에 이동시키고 싶은 크기만큼 값을 더해주어야 한다.

 

 

lealoop를 배울 수 있는 예제 교제 p/182 [Program using array]

; p/182 program using array

.386
.MODEL FLAT

INCLUDE io.h            ; header file for input/output


ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD

cr   EQU 0dh  ; carriage return
Lf   EQU 0ah  ; linefeed
maxNbrs  EQU 100  ; size of number array

.STACK 4096    ; reserver 4096-byte stack


.DATA 

directions   BYTE  cr, Lf, "You may enter up to 100 numbers"
    BYTE  " one at a time. ", cr, Lf
    BYTE  "Use any negative number to terminate"
    BYTE  "input.", cr, Lf, Lf
    BYTE  "This Program will then report the average and" 
    BYTE  "list", cr, Lf
    BYTE  "those numbers which are above the"
    BYTE  "average.", cr, Lf, Lf, Lf, 0
Prompt    BYTE  "Number?  ",0
number    BYTE  20 DUP (?)
nbrArray  DWORD  maxNbrs DUP (?)
nbrElts    DWORD  ?
avgLabel  BYTE  cr, Lf, Lf, "The average is"
outValue  BYTE  11 DUP(?), cr, Lf, 0
aboveLabel  BYTE  cr, Lf, "Above Average:", cr,Lf,Lf,0


.CODE    

_start :

; input numbers into array
    
  output   directions
  mov  nbrElts, 0
  lea  ebx, nbrArray
  
whilePos:  output  prompt
    input  number, 20
    atod  number
    jng  endWhile
    mov  [ebx], eax
    inc  nbrElts
    add   ebx, 4
    jmp   whilePos
endWhile:

    mov  eax, 0
    lea   ebx, nbrArray
    mov  ecx, nbrElts

    jecxz  quit

forCount1:  add  eax, [ebx]
    add  ebx, 4
    loop  forCount1

    cdq
    idiv  nbrElts
    dtoa  outValue, eax
    output   avgLabel
    output  aboveLabel
    
    lea  ebx, nbrArray
    mov  ecx, nbrElts

forCount2:  cmp  [ebx], eax
    jng  endIfBig
    dtoa  outValue, [ebx]

    output  outValue

endIfBig:  
    add  ebx, 4
    loop  forCount2

quit:    INVOKE ExitProcess, 0  ; exit with return code 0

PUBLIC _start    ; make entry point public
END      ; end of source code



  


** lea 명령어는 활용도가 높음으로 잘 익혀두는 것이 좋다.

 

Pipe의 개념

 

교재 p/189,

 

 

CPU의 기본 운영 사이클은 다음과 같다.

 

1. 메모리에서 명령어를 가져온다.(fetch)

2. 명령어를 해석한다.(decode)

3. 명령어를 실행한다.(execute)

 

 

각 연산자의 대한 클럭 사이클을 표에서 여러 번 보았다. 이 때의 한 사이클은 CPU1clock을 뜻한다.

 

CPU의 효율을 생각한다면 conditional jump는 좋지 않다. 때문에 조건문을 최소화 하는 것이 pipelining을 최적화하는 방법이다.

 

 

 

chapter에서는 if, 다양한 반복문과 배열에 대해서 배웠다. jmp명령어는 무조건 이동(c에서 goto문과 같은 역할), 조건이동은 플래그의 상태와 operand를 비교함으로써 반복문을 다시 수행할지 빠져나올지 아니면 표시된 자리로 이동할지를 결정한다. loop문은 ECX 레지스터에 들어있는 수에서 -1을 함으로써 ECX 값이 0이 될 때까지 수행하게 된다. 만약 ECX레지스터가 초기에 0이라면 jecxz 명령어를 사용하여 빠져 나올 수 있다. lea 명령어는 변수에 있는 주소 값을 ECX레지스터에 복사하는 역할을 한다. 파이프라이닝은 CPU의 사이클인 fetch-decode-execute가 수행되는 절차와 조건 문이 사용될 때 컴파일 시 파이프라이닝이 초기화됨을 보여줌으로써 효율적인 프로그램을 작성하는데 필요한 CPU 작동 원리를 알려준다.

 

 

p/193 Chapter 6. Procedures

 

1. 80X86 Stack

 

자주 언급해온 메모리의 5대 영역중의 하나인 stack영역은 메모리의 시작번지와 끝 번지가 있다고 치면 끝 번지에서 시작한다.(완전히 끝은 아니지만 개념상 끝이라고 한다.) 메모리의 끝 부분이 stackbase 포인트, 즉 출발 시점이 된다. 이 때 사용되는 레지스터 EBP는 스택 메모리의 시작점이고 스택이 커질수록 ESPbase에서 멀어진다.

 

 

** 프로시져에 관한 내용은 블로그에 비공개로 올려 놓아야 한다.

 

 

esp를 옮기는 명령어는 push이다. 1bytepush되지 않는다.

stack은 최소 2byte 단위로 표시된다. 메모리가 개입할 때 속도가 느려지는 것을 알 수 있다.

push한다는 것은,

 

1. 스택 주소 = 스택 주소 - push한 크기(스택의 크기를 늘리는 작업)

2. 현재 주소 = 값 대입

우선 stack을 확장하고 난 후에 확장된 stack 공간에 자료가 삽입되게 된다.


 

 

pop명령어는 stack에 있는 자료를 꺼내어 레지스터에 저장하기 때문에 immediateoperand로 올 수 없다.

; push instruction

.386
.MODEL FLAT



ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD



.STACK 4096    ; reserver 4096-byte stack


.DATA 




.CODE    

_start :

mov   eax, 83B5h
push   ax
push  0FFFFFF10h




; input numbers into array
    


quit:    INVOKE ExitProcess, 0  ; exit with return code 0

PUBLIC _start    ; make entry point public
END      ; end of source code



  





 

반응형
Posted by newind2000