TITLE Reversing a String (RevStr.asm)
INCLUDE Irvine32.inc
.data
aName BYTE "Abraham Lincoln", 0 ; 역순으로 배치할 문자열을 선언합니다
nameSize = ($ - aName) - 1 ; aName에 대해 문자열의 길이를 구하는 부분인데, 여기서 $ 는
; 현재 명령어의 위치 주소 입니다. 현재 주소에서 aName의 주소를
; 빼게 되면 문자열의 길이만 남게 되는데, 여기서 널문자를 제외하기 위해 - 1 을
; 해줍니다.
; 현재 명령어의 위치 주소 입니다. 현재 주소에서 aName의 주소를
; 빼게 되면 문자열의 길이만 남게 되는데, 여기서 널문자를 제외하기 위해 - 1 을
; 해줍니다.
.code
main PROC
; 스택으로 문자를 push 하는 부분
; 스택으로 문자를 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'을 꺼내옵니다.
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
이코드에서 바른구문과 역순의 구문을 출력하는 코드로 바꾸려면?
그리고 역순의 구문을 저장한 메모리가 있어야 한다면 무엇을 더 추가해야 될까?
c로 짠다음 옮겨보세요
제가질문할게요 님아 어셈블리어 독학하심?
간찰스한테 물어보셈