2010-02-22 2 views
2

저는 Assembly (그리고 일반적으로 솔직히 프로그래밍)에 익숙하지 않습니다. 나는 스택을 가지고 노는 중이 야. 이 코드의 목적 : 제한된 문자열에서어셈블리 - 문자열을 뒤집어 쓰려고하지만 최종 문자열에 여분의 문자가 추가됩니다.

  • 테이크, 80 자
  • 재 인쇄가 스택
  • 인쇄 각에 밀려으로
  • 인쇄 각 문자를 입력 한 문자열 스택에서 튀어 나오는 문자
  • 역순 문자열을 인쇄하십시오.

코드가 마지막 단계에서 실패합니다.

입력 한 문자열이 "도움말"이면 "pleHe"가 인쇄됩니다. 마지막 String의 마지막 문자는 원래 String의 두 번째 문자입니다.

내가 어수선한 곳을 볼 수 있도록 도와주세요!

.data 
buffer WORD 81 DUP(0) 
byteCount WORD ? 
.code 
main PROC 
    call Clrscr     ;Clear screen   
RS: 
    mov edx, OFFSET buffer  ;Move String to edx 
    mov cl, [SIZEOF buffer]-1 ;Set loop counter to (size of buffer) -1 
    call ReadString    ;Read a User's String 
    mov byteCount, ax   ;Move the size of User's String to byteCount 
    cmp byteCount, 80   ;Compare byteCount with 80 
    ja RS      ;If byteCount is greater then 80, ask for another String 
    call WriteString   ;Write User's String to screen 
    call Crlf     ;New Line 
    call reverseIt    ;Reverse order of String 
    exit 

reverseIt PROC 
    movzx ecx, byteCount  ;Set Loop1 Counter to size of String 
    mov esi, 0     ;Zero out ESI 

L1:        ;Loop1 - Pushes String into Stack one character at a time 

    movzx eax, buffer[esi]  ;Dereference buffer and place in eax 
    call Crlf     ;New Line 
    call WriteChar    ;Print current character to screen 
    push eax     ;Push current character to stack 
    inc esi      ;Move to next character 
    loop L1 

    call Crlf 
    movzx ecx, byteCount  ;Set Loop2 Counter to size of String 
    mov esi, 0     ;Zero out ESI 

L2:        ;Loop2 - Pops Characters back into String in reverse order 

    pop eax      ;Retrieve character from top of stack 
    call Crlf     ;New Line 
    call WriteChar    ;Print current character to screen 
    mov buffer[esi], ax   ;Writes character to String 
    inc esi      ;Increase esi 
    loop L2 

    call Crlf     ;New Line 
    call Crlf     ;New Line  
    mov edx, OFFSET buffer  ;Move String to edx for WriteString 
    call WriteString   ;Prints String to Screen 
    call Crlf     ;New Line 
    ret       ;Return to main 
    reverseIt ENDP 
main ENDP 
END main
+2

디스어셈블러를 통해 단계별 처리하십시오. 두 번째 "e"가 버퍼에 추가되는 위치를 찾아보십시오. –

답변

4

문제

한 번에 두 문자를 반대로 결국 있도록, 오히려 바이트보다 WORD를로 ASCII 문자를 치료하고 있습니다 :

당신은 문자열을 두 문자에서 반전 할 때 시간이 지나면 버퍼에이 값을 쓰게됩니다.

esi+0: p- 
esi+1: lp 
esi+2: el 
esi+3: He 

버퍼가 반복 될 때마다 버퍼가 좋아 보입니다. 이 경우 :

Help-- 
p-lp-- 
plpp-- 
plel-- 
pleHe- 

그래서 여분의 e를 버퍼에 씁니다. WriteChar 루프에 e가 나타나지 않는다고 가정합니다.

솔루션

나는 확실히 알 수 있도록 코드를 테스트하지 않은,하지만이 라인을 변경해야 할 것 같습니다 :

mov buffer[esi], ax   ;Writes character to String 

mov ptr byte buffer[esi], al   ;Writes character to String 
로를

이 줄을 변경하는 것이 좋습니다.

buffer WORD 81 DUP(0) 

그래서 대신 바이트를 사용

buffer BYTE 81 DUP(0) 
+0

감사합니다. –

0

이 주셔서 감사합니다! 문자열의 크기를 제한하는 첫 번째 부분이 BYTE와 작동하지 않았기 때문에 BYTE 대신 WORD를 사용한다는 것을 알고있었습니다. 그것은 중간에 끈을 자르고있었습니다.

그래서 버퍼를 BYTE로 변경하지 않았습니다.

다른 말로하면 (나는 이전에 시도한 것 같은) 다른 변경을 시도했지만 양쪽 피연산자가 같은 크기 여야한다는 컴파일 오류가 계속 발생했습니다.

캐스팅 버퍼 [esi]를 바이트로 고정했습니다! 이제 완벽하게 작동합니다! 감사!

+0

올바른 방법은 버퍼를 BYTE 배열로 선언하는 것입니다 (지금은 162 바이트 - 81 * 2 인 버퍼를 선언하고 있습니다). 내 생각 엔'ReadString'을 호출 한 후'ax'에서 잘못된 결과를 얻었을 것입니다. 어떻게 이것을 해결할 수 있는지 대답하기 위해 ReadString의 구현 방법을 보여줄 필요가 있습니다. 'Bytecount'는 한 바이트가 문자열의 최대 값인'80 '을 가질 수 있기 때문에 BYTE로 선언 될 수 있습니다. – Cyclonecode

관련 문제