1

I am working on an assignment identical to 20 Random Strings containing all capital letters

I need to create a procedure that generates a random string of length L, containing all capital letters. When calling the procedure, I need to pass the value of L in EAX, and pass a pointer to an array of byte that will hold the random string. Then I need to write a test program that calls your procedure 20 times and displays the strings in the console window.

I believe that I have gotten much closer to a solution thanks to the answers there but still have one (I hope) issue. Microsoft Visual Studio 2017 throws the following error:

Exception thrown at 0x004036BE in Project.exe: 0xC0000005: Access violation writing location 0x0080C036. occurred

The error takes place on line 41: mov arr1[EBX], AL

So my best guess is that I have miscalculated the target address of the array but I'm not sure how? I get the error on the 1st run of that loop.

; Random Strings.

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

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


.code
main PROC
    mov EDX, OFFSET str1      ;"The c20 random strings are:"
    call WriteString          ;Writes string
    call Randomize
    call Crlf                 ;Writes an end - of - line sequence to the console window.
    mov ECX, numberStrings    ;Main Loop Counter Create 20 strings
    mov ESI, OFFSET arr1      ;ESI: array address

L1 : 
    mov EAX, strLen            ;EAX: string length
    call RandomString          ;generates the random string
    call Display               ;displays the random string to console
    mov AL, TAB                ;moves tab to register to be passed to WriteChar
    call WriteChar             ;leaves a tab space
    exit
main ENDP

RandomString PROC USES EAX ESI
    mov ECX, EAX               ;ECX = string length
    mov EBX, ESI               ;store array address

    FillStringWithRandomCharacters : 
        mov EAX, 26            ;set upper boundry for RandomRange call
        call RandomRange       ;called with 26 so range will be 0 - 25
        add EAX, 65            ;EAX gets ASCII value of a capital letter
        mov arr1[EBX], AL      ;pass 8 bits of EAX to array
        inc EBX                ;move array target address
    loop FillStringWithRandomCharacters

    ret
RandomString ENDP

Display PROC USES EAX ESI      ;Displays the generated random string
    mov ECX, EAX               ;ECX = string length
    mov EBX, ESI               ;store array address

    DisplayRandomString : 
        mov AL, arr1[EBX]      ;retrieve char from array
        call WriteChar         ;writes the char to console
        inc EBX                ;move array target address
    loop DisplayRandomString

    ret
    Display ENDP

    call dumpregs

INVOKE ExitProcess, 0
END main
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • When does `FillStringWithRandomCharacters` stop? Looks like it's an infinite loop that will keep overwriting memory with a random string. Also, don't forget to reserve space for the null terminator. – Havenard Mar 07 '18 at 01:52
  • Step in to your code. What value does `EBX` have at the point you're attempting to index `arr1`? – Simon Whitehead Mar 07 '18 at 01:53
  • 1
    Also doesn't look like `arr1` can fit 20 strings, but 20 bytes. – Havenard Mar 07 '18 at 01:53
  • Nevermind, I just learned that `loop` in MASM is a high level instruction that doesn't do the same as a simple `jmp`. – Havenard Mar 07 '18 at 01:59
  • 1
    @Havenard: `loop` isn't a pseudo-instruction or special NASM macro, it's a real x86 instruction. [But it's slow and not recommended](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently) – Peter Cordes Mar 07 '18 at 02:05
  • 2
    Your code formatting is hard to read. The usual (and good) style is to Indent instructions one level more than labels. Also, indent comments far to the right, instead of starting them right at the end of every instruction. It turns you code into a wall of text when you can't easily tell the operands from the comments. (Wouldn't be as bad if Stack Overflow had colour syntax highlighting for asm comments, but it doesn't.) – Peter Cordes Mar 07 '18 at 02:11
  • Isn't `ebx` already a pointer to the array? So `arr1[ebx]` is like `[ebx+ebx]` on the first iteration, and accesses an address twice as high as what you want. Just use `[ebx]`. Or use `[ebx+ecx-1]` because you already have a loop counter in `ecx`; you don't also need `inc ebx`. – Peter Cordes Mar 07 '18 at 02:15
  • 1
    @PeterCordes that was it - thank you. Which opened up my next error of not marking L1 as a loop. Once I did that this program worked perfectly. – imagesrdecieving Mar 07 '18 at 02:38
  • Nice improvement in the code formatting; makes a huge difference. BTW, you still have a useless `call dumpregs` outside of any function. If execution fell off the end of `main`, (past the `exit` macro or whatever that is), it would fall into the next function, so either way `call dumpregs` and `INVOKE ExitProcess, 0` can't be reached. – Peter Cordes Mar 07 '18 at 04:17
  • 1
    @PeterCordes you can exploit `language: lisp` setting to get simpler masm/tasm/nasm sources on SO to be somewhat reasonably highlighted (edited the Q to show how it will end). (and `bash` or something like that for asm variants where `#` is comment) OP: use rather debugger than `dumpregs`, and trace the whole code by single-stepping, learning how to use debugger will save you ton of time later, when just dumping registers will be not enough to explain some tricky bug. – Ped7g Mar 07 '18 at 07:24

0 Answers0