2

Ultimately, what I am trying to do is make requestInput repeat 25 times and store the input it receives from each iteration into the following index in theSINTArray, but I'm not sure how to put something into an array. The looping I will take care of later, but how would I make it so that the first iteration of requestInput puts the received input into index 0, the second iteration puts the received input into index 1 and so on?

.data
theSINTArray BYTE 25 dup(?)              
prompt BYTE "Please enter a value: ",0


.CODE

main PROC

push    TYPE theSINTArray
push    LENGTHOF theSINTArray
push    OFFSET theSINTArray
call    requestInput
exit

main ENDP

requestInput PROC

push    edx                                        
mov     edx,OFFSET prompt                          
mov     edi,OFFSET theSINTArray                    
call    WriteString                                
call    ReadInt                                    
pop     edx                                        
ret

requestInput ENDP


END     main

My second attempt based on the answer by @SepRoland:

.data
theSINTArray BYTE 25 dup(?)              
prompt BYTE "Please enter a value: ",0


.CODE

main PROC

push    TYPE theSINTArray
push    LENGTHOF theSINTArray
push    OFFSET theSINTArray
call    requestInput
exit

main ENDP

requestInput PROC

Next:
push    edx                                        
mov     edx,OFFSET prompt                          
call    WriteString                                
call    ReadInt 

mov     edx, offset theSINTArray
mov     [edx], al
inc     edx
cmp     edx, offset theSINTArray + 25
jb      Next

pop     edx                                        
ret

requestInput ENDP


END     main
Fifoernik
  • 9,779
  • 1
  • 21
  • 27
Proto
  • 99
  • 5
  • `mov edx, offset theSINTArray` inside the loop will reset it each run, and you'll always store in the first byte. this is an endless loop – Tommylee2k Apr 11 '16 at 06:41

1 Answers1

1

You defined theSINTArray as an array of bytes, so you'll need an instruction such as mov [edx], al to store the value and then use inc edx to point to the next element in the byte sized array.

 mov   edx, offset theSINTArray
Next:
 call  requestInput
 mov   [edx], al
 inc   edx
 cmp   edx, offset theSINTArray + 25
 jb    Next

In response to your effort to put the value-assignment within the requestInput procedure.

  • You've put the Next label above the push edx instruction. This means that the pop edx must be done within the loop.
  • You've re-initialized the pointer on each iteration, and so will always be writing in the first array element. Move this above the loop.

This is how:

requestInput PROC
 mov     edx, offset theSINTArray
Next:
 push    edx                                        
 mov     edx,OFFSET prompt                          
 call    WriteString                                
 call    ReadInt
 pop     edx 
 mov     [edx], al
 inc     edx
 cmp     edx, offset theSINTArray + 25
 jb      Next
 ret
requestInput ENDP
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Due to my inexperience with assembly language, I have a few questions before I attempt to utilize your solution. 1. What is the significance of the brackets around edx? 2. I am aware that you are placing AL into EDX because only an "8 bit portion of EAX" will be able to fit into one of the array's indexes, but why was AL chosen over AH? 3. What is the significance of the "+ 25" in the cmp line? – Proto Apr 10 '16 at 21:47
  • *ReadInt* delivers a result in EAX. If you know numbers are in the byte range [-128,+127] then you'll find these in the lowest byte of EAX. Thus AL. – Sep Roland Apr 10 '16 at 21:51
  • The use of square brackets is required to address memory through a pointer placed in a register such as EDX. – Sep Roland Apr 10 '16 at 21:52
  • 1
    The `offset theSINTArray` together with **+25** mark the end of your array. This way I eliminated the need for a separate loop-control variable. – Sep Roland Apr 10 '16 at 21:55
  • I realized soon after my last post that the code in your example seemed to be intended to be placed under .CODE. I attempted to implement it into the requestInput subroutine and edited my original post's code with the result. Would that code have the same effect yours? – Proto Apr 10 '16 at 23:12
  • 1
    Worth pointing out that the OP's code treats `edx` as a call-preserved register, while in the normal ABIs functions are allowed to modify edx without saving/restoring it. The normal way to handle this is to use a call-preserved register like `ebx` for the loop variable. (Then `main` has to save/restore `ebx` if it wants to return instead of calling `exit`, but `requestInput` doesn't have to save/restore anything). @Proto: In asm, it's ok to write functions that know about each other and make assumptions based on how the called function behaves, but don't do that when there's no advantage. – Peter Cordes Apr 11 '16 at 00:23
  • @SepRoland Thank you for all of the assistance you have provided so far. However, I do have one final amateur question. Let's say I wanted to access the elements stored in indexes 3, 7, or any indexes of the array and compare them. What would be the syntax of a line of code that would allow me to do such a thing? – Proto Apr 11 '16 at 18:12
  • @Proto Since the array is an array of byte-sized elements, you can use the index as an offset and just write: `mov al,[edx+3]` `cmp al,[edx+7]`. If p.e. you got one index in ECX and the other index in EBX then you would write: `mov al,[edx+ecx]` `cmp al,[edx+ebx]`. – Sep Roland Apr 11 '16 at 20:14
  • Ah, I see. Thank you very much for your help. My understanding assembly has grown noticeably thanks to your assistance. – Proto Apr 11 '16 at 22:08