2017-10-31 18 views
1

모든 대문자가 포함 된 길이가 L 인 임의의 문자열을 생성하는 절차를 만들어야합니다. 프로 시저를 호출 할 때 EAX에서 L의 값을 전달하고 임의의 문자열을 보유 할 바이트 배열에 대한 포인터를 전달해야합니다. 그런 다음 프로 시저를 20 번 호출하고 콘솔 창에 문자열을 표시하는 테스트 프로그램을 작성해야합니다.20 대문자가 모두 포함 된 임의의 문자열

아래 코드는 늘는 이러한 오류가 돌아 오면 작업 :

Line (33): error A2008: syntax error : main ENDP 
Line (35): error A2144: cannot nest procedures 
Line (46): error A2008: syntax error : RandomString 
Line (48): error A2144: cannot nest procedures 
Line (59): warning A6001: no return from procedure 
Line (66): fatal error A1010: unmatched block nesting 

나는 내가 잘못을하고 어떻게 이러한 오류를 수정하고있는 무슨에 어떤 아이디어 ... 어셈블리 언어로 여전히 매우 새로운 오전? 고맙습니다.

;Random Strings. 

INCLUDE Irvine32.inc 
TAB = 9      ;ASCII code for Tab 
strLen=10      ;length of the string 

.386 
.model flat,stdcall 
.stack 4096 
ExitProcess PROTO, dwExitCode:DWORD 

.data 
str1 BYTE"The 20 random strings are:", 0 
arr1 BYTE strLen DUP(?) 

.code 
main PROC 
    mov ed x, OFFSET str1   ;"The c20 random strings are:" 
    call WriteString    ;Writes string 
    call Crlf      ;Writes an end-of-line sequence to the console window. 
    mov ecx,20     ;Create 20 strings 

L1: mov esi,OFFSET arr1   ;ESI: array address 
    mov eax,strLen    ;EAX: string length 
    call RandomString    ;generates the random string 
    call Display 
    mov al,TAB 
    call WriteChar    ;leaves a tab space 
    exit 
main ENDP 

    RandomString PROC USES eax esi 
    mov ecx,eax     ;ECX = string length 

L1: mov eax, 26 
    call RandomRange 
    add eax,65     ;EAX gets ASCII value of a capital letter 
    mov arr1[esi],eax 
    inc esi 

    loop L1 

    RandomString EXDP 

    Display PROC USES eax esi  ;Displays the generated random string 

    mov ecx,eax     ;ECX=string length 

L1: mov eax, arr1[esi]   ;EAX = ASCII value 
    call WriteChar    ;writes the letter 

    inc esi 

    loop L1 

    Display ENDP 


     call dumpregs 

     INVOKE ExitProcess,0 

END main 
+0

사용중인 아키텍처 및 어셈블러에 태그하십시오. –

답변

2
  • ENDP 지시어는 라벨 없다. 그리고 오타없이. 너의 것은 작동하지 않으므로 다음 PROC 지시문은 MASM에서 합법적이지 않은 프로 시저 내에서 중첩 된 프로 시저를 엽니 다.

  • mov arr1[esi],eax은 하나가 아닌 4 바이트를 저장합니다 (마지막 3 자이고 버퍼는 10 바이트 길이 일 때 고려하십시오).

  • ENDP는 MASM 지시문이 아닌 명령이다, 그래서 당신의 RandomString 코드는 다음 메모리에 될 일이 무엇이든 loop 명령, 후 뭔가을 실행하는 것입니다. ret instruction에 관심이있을 수 있습니다. 서브 루틴 Display도 확인하십시오.

  • RandomString은 입력 버퍼로 대상 버퍼의 주소를 설정하는 곳으로 esi을 사용합니다. 그런 다음 mov arr1[esi],...을 수행하므로 arr1+arr1 주소 계산이 수행되어 잘못된 메모리 액세스 (또는 자동 메모리 덮어 쓰기 어딘가에을 덮어 쓸 수 있지만 확실히 버퍼에 저장되지는 ​​않습니다.)가 발생합니다. 버퍼에 대한 포인터가 이미 포함되어 있다면 mov [esi],...이면 충분합니다.

  • Displayesi를 사용하지만 앞서 call Display의 설정하지 않기 때문에 그것은 RandomString이 남아 어떤 esi에서 찾을 수 있습니다. 그리고 다시 arr1[esi], 즉 arr1+esi 주소 계산을합니다.

  • "EAX = ASCII 값" ... 나는 아스키 값이 8 비트 만 필요하고 메모리에서 32 비트를로드한다는 점을 매우 의심 할 것입니다. 이 시점에 eax에는 4자를 포함 할 가능성이 큽니다. 그러나 WriteChareax의 아래쪽 8 비트만을 사용하므로 예상대로 작동하지만 여전히 일종의 버그이며 네이티브 CPU 데이터 유형/레지스터에 대한 오해/무지를 보여줍니다.

  • 레이블이 여러 개 있는데, L1 레이블이 있는데, 나는 그것이 MASM에서 글로벌하다고 생각했지만 (아마도 PROC이 지역화 할 것입니다). 전반적으로 내가 코드 레이블 L1에 있음을 알리면, 그게 무엇에 사용되는지에 대해 무엇을 말합니까? 어쨌든 코드 이름을 AlienInvasionV4_HandlerOfMultidimensionalTeleportationError:으로 변경하면 코드를 보지 않고도 해당 기능에 대해 추측 할 수 있습니까? "L1"처럼 무언가를 사용하는 것이 요점은 무엇입니까?

  • main에 루프가 없습니다.

  • RandomStringecx으로 변경됩니다 (심지어 main에 루프가있을 경우에도 예상대로 작동하지 않음).

  • Displayeax 값을 입력으로 사용하려고 시도하지만이를 call Display 앞에 설정하지 마십시오.

... 어쩌면 좀 더 버그,하지만 난 그것을 통해 독서의 피곤있어 (나는 창문 실제로 그것을 실행 + 어바인 lib 디렉토리가없는, 그래서 내 모든 노트는 소스 및 실행을 교정하여 있습니다 그 머리에 ... 당신도 너 자신 후에 그것을 읽을 수 있다고 상상해라. 그리고 각 지시에 관해서 이유를해라.) ... 당신은 당신이 여기에서 무엇을 요구하고 있는지에 관해 당신 자신의 것으로 대부분을 고칠 수 있어야한다. 그래서. 더 많은 것은 잘못된 문법 오류를 수정하는 것보다 지루한 것입니다 (ENDP). 코드가 알고리즘의 정상 성을 엿볼 수는 있지만, CPU를 전혀 이해하지 못하는 것처럼 완전히 단서를 느끼지는 못합니다 (레지스터의 "슈퍼 글로벌"성격을 놓치고 호출을 통해 가치를 유지할 것을 기대하는 것을 제외하고), 정확성과 경험의 ASM으로 훨씬 더 많은 정밀도가 필요합니다. 기계는 결과에 대한 경고없이 귀하가 던지는 모든 법적 지침을 기꺼이 실행합니다.