본문 바로가기

컴퓨터 공학 자료(학부)/Assembly

어셈블리어 과제


개발환경: 비쥬얼 스튜디오 2008+ MASM 연동해서 프로그래밍


술취한 교수라고 어셈블리책 10장 구조체에 나오는 예제인데 시간이 없어서
무식하게 짰다.
처음시작 좌표 25,25를 지정해주고 랜덤으로 길을 한칸씩 가게해서 50,50(교수님의집) 까지 갔을때
종료하는 프로그램이다.
50,50 맵을 지정해주었고
중간중간에 전봇대를 세워줘서 교수님이 전봇대에 부딫치면 뒤로 한발짝 다시 물러서게 하였다.


INCLUDE irvine32.inc

walkMAX =1000
StartX = 25
StartY = 25

DrunkardWalk STRUCT
 path COORD WalkMax DUP(<0,0>) ;COORD 구조체: 윈도우 API기본 제공 구조체
 pathUsed WORD 0      ;.model stdcall 오른쪽에서부터 왼쪽으로 넣고 스택에서는 왼쪽부터 뽑음
DrunkardWalk ENDS

DisplayPosition PROTO currX:WORD, currY:WORD ;call은 함수 인자를 전달할 수 없다
            ;proto 한 다음 invoke해야 함
.data
aWalk DrunkardWalk <>
comma BYTE "crash!!!",0
.code
main PROC
 mov esi,offset aWalk
 call TakeDrunkenWalk
 exit
main ENDP

TakeDrunkenWalk PROC

LOCAL currX:WORD, currY:WORD ;LOCAL은 지역변수 사용법(변수명:타입명)
 pushad
 mov edi,esi
 add edi,OFFSET DrunkardWalk.path
 mov currX,StartX
 mov curry,StartY
 
 
  
 .WHILE 1
  mov ax,currX
  mov (COORD PTR [edi]).X,ax
  mov ax,currY
  mov (COORD PTR [edi]).Y,ax
  
  INVOKE DisplayPosition, currX, currY
  
  mov eax,6 ;
  
  call RandomRange
  
  .IF eax == 0 && currY <50
   inc currY
  .ELSEIF eax == 1 && currY >0
   dec currY
  .ELSEIF eax == 2 && currX >0
   dec currX 
  .ELSEIF eax ==3 && currX <50
   INC currX
  .ELSEIF eax ==5 && currX <50 && currY <50
   INC currX
   INC currY
  .ENDIF
  
  .IF currX == 21 && curry ==14 ; (21,14)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 21 && curry ==22 ; (21,22)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 31 && curry ==14 ; (31,14)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 44 && curry ==14 ; (44,14)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 44 && curry ==49 ; (44,49)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 26 && curry ==24 ; (26,24)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 15 && curry ==24 ; (15,14)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 12 && curry ==17 ; (12,17)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 50 && curry ==48 ; (50,48)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기
  .ELSEIF currX == 47 && curry ==50 ; (37,50)에 있는 전봇대 만나면  뒤로한칸 왼쪽으로 한칸 물러남
   DEC currX
   DEC currY
   MOV EDX, OFFSET comma
   call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
   call Crlf   ;irvine 함수 한줄 띄우기 
  .ENDIF
  
  add edi,TYPE COORD
  .IF currX == 50 && currY ==50
   jmp FINISH
  .ENDIF
 .ENDW
 

FINISH:
  add edi,TYPE COORD
  INVOKE DisplayPosition, currX, currY
 
 popad
 ret
TakeDrunkenWalk ENDP

DisplayPosition PROC currX:WORD, currY:WORD
.data
commaStr BYTE ",",0
.code
 pushad
 movzx eax,currX ;movzx 낮은쪽 먼저 들어가고 나머지 빈공간에는 0을 채움
 call WriteDec ;irvine 함수
 mov edx,OFFSET commaStr ;
 call WriteString ;호출될 당시 edx값에 있는 주소값을 찾아감 (null 문자 나올때까지)
 movzx eax, currY
 call WriteDec ;irvine 함수
 call Crlf   ;irvine 함수 한줄 띄우기
 popad
 ret
DisplayPosition ENDP
End main