Programming/Assembly2012. 1. 26. 18:58


"인텔 기반 컴퓨터를 위한 어셈블리 언어 5판" 은 어제부터 시작한 어셈블리 교재입니다.

공부하면서 풀은 연습문제입니다.


1번 - 텍스트 색상 그리기

TITLE 5.8.1 example

; 5.8.1
; 텍스트 색상 그리기

 
INCLUDE Irvine32.inc
.data
printMsg BYTE "Assembly language - NullBr4in - ajlab.tistory.com", 0

.code
main PROC
mov eax, yellow
call SetTextColor
mov edx, OFFSET printMsg
call WriteString
call Crlf

mov eax, green
call SetTextColor

call WriteString
call Crlf

mov eax, cyan
call SetTextColor

call WriteString
call Crlf

mov eax, lightRed
call SetTextColor

call WriteString
call Crlf

mov eax, lightgray
call SetTextColor

exit
main ENDP
END main



2번 - 피보나치 수의 파일
 
 

 
Posted by NullBr4in
Programming/Assembly2012. 1. 26. 18:03


어셈블리어 명령어 정리는 시간 날때마다 한번씩 내용을 추가하겠습니다 ( 2012-01-26 )


 어셈블리어 명령어에 대해 정리할때 아래와와 같은 표기법을 이용해서 정리하겠습니다. 
 
  [그림 1] 인텔 IA-32 메뉴얼에서 채택한 피연산자에 대한 간단한 표기법



 MOV 
 - MOV 명령어는 소스 피연산자로부터 목적지 피연산자로 데이터를 복사한다.
 - MOV 복사하고자 하는 목적지, 복사할 대상이 있는 곳
 - MOV destination, source
 - MOV 명령어는 dest = source 와 같다 

 - MOV 명령어의 규칙
  + 두 피연사자는 같은 크기이어야 한다.
  + 두 피연산자는 모두 메모리 피연산자일 수는 없다.
  + CS, EIP, IP는 목적지 피연산자일 수 없다.
  + 즉시값은 세그먼트 레지스터로 이동될 수 없다.
 
 - 세그먼트 레지스터를 제외한 일반적으로 사용하는 MOV의 형태들이다.
  + MOV reg, reg
  + MOV mem, reg
  + MOV reg, mem
  + MOV mem, imm
  + MOV reg, imm

 - MOV 명령어를 사용할 때 한 메모리에서 다른 메모리 위치로 이동시키는데 사용하지 못한다.
   그러므로 다음의 방법을 사용한다.
  + var1, var2 는 WORD 형태를 가지고 있습니다.
    mov ax, var1
    mov var2, ax

 
Posted by NullBr4in
Programming/Assembly2012. 1. 23. 17:11


5.4.2 장에서 스택을 이용한 문자열을 역순으로 배치하는 예제 입니다.

고급언어를 만지다가 저급언어를 만지게 되니  저급언어가 방법도 여러가지에 효율적이라고 생각되네요.



 TITLE Reversing a String (RevStr.asm)

INCLUDE Irvine32.inc
.data
aName BYTE "Abraham Lincoln", 0 ;  역순으로 배치할 문자열을 선언합니다
nameSize = ($ - aName) - 1 ; aName에 대해 문자열의 길이를 구하는 부분인데, 여기서 $ 는 
                                                                ; 현재 명령어의 위치 주소 입니다. 현재 주소에서 aName의 주소를
                                                                ; 빼게 되면 문자열의 길이만 남게 되는데, 여기서 널문자를 제외하기 위해 - 1 을
                                                                ; 해줍니다. 

.code
main PROC

; 스택으로 문자를 push 하는 부분 
mov ecx, nameSize                            ; 반복문에서 사용할 count 레지스터인 ecx에 문자열의 길이를 넣어줍니다.
mov esi, 0                                          ; esi에는 0으로 초기화 시켜줍니다. esi는 간접 피연산자를 이용한 간접 주소 지정
                                                                ; 을 통해 문자열을 하나하나 가리키게 됩니다. 

L1:                                                            ; L1 루프의 시작
movzx eax, aName[esi]                     ; aName+esi 위치의 문자열을 eax로 이동시켜줍니다. aName+0, aName+1 이런식
push eax                                           ; eax를 스택에 추가하고 - L,i,n,c,o,l,n,,, 이런식으로 스택에 쌓이게 됩니다.
inc esi                                               ; esi를 1증가시킵니다 - 다음 반복에서 다음 문자를 가리키기 위함입니다.
loop L1                                              ; L1의 처음부분으로 가서 반복합니다.

; 아래는 스택에서 문자를 pop 하는 부분.

mov ecx, nameSize                             ; 반복이 끝나면 0이 된 ecx에 다시 문자열의 길이를 넣어줍니다.
mov esi, 0                                           ; esi 또한 0으로 초기화 합니다

L2:
        pop eax                                              ; pop을 하여 스택의 맨 나중에 들어간 'n'을 꺼내옵니다.
mov aName[esi], al                            ; 꺼내온 값을 [aName+esi] 에 넣습니다.
inc esi                                               ; esi를 1 증가시킵니다.
loop L2                                              ; 루프의 처음으로 돌아갑니다

; 역 배치가 끝나고 출력 하는 부분.

mov edx, OFFSET aName                     ; aName의 offset을 edx에 저장합니다.                  
call WriteString                                      ; WriteString 함수는 edx에 저장된 주소의 위치에 있는 문자열을 출력합니다.
call Crlf                                               ; 개행
exit                                                    ; 종료
main ENDP
END main


Posted by NullBr4in