包含所有大写字母的20个随机字符串

时间:2017-10-31 03:27:50

标签: string assembly random x86 masm

我需要创建一个生成长度为L的随机字符串的过程,其中包含所有大写字母。在调用过程时,我需要在EAX中传递L的值,并将指针传递给将保存随机字符串的byte数组。然后我需要编写一个测试程序,调用你的程序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

1 个答案:

答案 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],...已足够,如果它已包含指向缓冲区的指针。

  • Display使用esi,但您未将其设置在call Display之前,因此无论esi是什么,它都会在RandomString中找到离开那里。并且它再次arr1[esi],即arr1+esi地址计算。

  • “EAX = ASCII值” ...我非常怀疑,因为ASCII值只需要8位,所以从内存中加载32位。此时eax很可能包含4个字符。但是WriteChar将仅使用eax的底部8位,因此它将按预期工作,但它仍然是一种错误,表明您对本机CPU数据类型/寄存器的误解/忽略。

  • 有多个L1标签,我认为它们在MASM中是全局的(但也许PROC会将它们本地化)。总的来说如果告诉你我的代码标签L1,它对你说的用途是什么?如果我将它重命名为AlienInvasionV4_HandlerOfMultidimensionalTeleportationError:怎么样,即使没有看到代码,你能猜出它的功能吗?使用像“L1”这样神秘的东西有什么意义?

  • main中没有循环。

  • RandomString将更改ecx(即使main中存在循环,它也无法按预期工作)。

  • Display会尝试同时使用eax值作为输入,但不要将其设置在call Display之前。

...也许还有一些错误,但我厌倦了阅读它(我没有windows + irvine lib来实际运行它,所以我的所有笔记都只是通过校对你的源代码并在头脑中运行它。 ..想象一下,你也可以自己阅读并理解每一条指令,哇!)...你应该能够自己找到+修复大部分这些,不知道你在这里问的是什么。与使用错误使用的ENDP修复一些语法错误相比,它会更加更多乏味。虽然你的代码已经看到了算法的健全性,但是你并不觉得完全无法理解CPU(除了你错过了寄存器的“超全局”特性并希望它们保持其值超过调用),更像缺乏精确和经验。使用ASM需要更高的精确度,机器将很乐意执行您向其投掷的任何法律指令,而不会对后果发出任何警告。