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
|
'Programming > Assembly' 카테고리의 다른 글
[인텔 기반 컴퓨터를 위한 어셈블리 언어 5판] 연습문제 풀이 5장 (2) | 2012.01.26 |
---|---|
어셈블리어 명령어 정리 (0) | 2012.01.26 |
[인텔 기반 컴퓨터를 위한 어셈블리 언어] GetMSeconds를 이용한 성능 시험 (0) | 2012.01.23 |
[인텔 기반 컴퓨터를 위한 어셈블리 언어] 난수(Random) 생성 (0) | 2012.01.23 |
[인텔 기반 컴퓨터를 위한 어셈블리 언어] 5.3.3 라이브러리 테스트 프로그램 (0) | 2012.01.23 |