NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: dstudentx on April 11, 2010, 09:40:20 PM
-
why can't I store a integers into and array, well two arrays for that matter.
all I'm trying to do is store user input (integers) into an array, then store another set of user input of integers into another array. my first while loop ends after three inputs and my second while loop ends after 1 input. and only the last integer input seems to be stored into the array.
%include "asm_io.inc"
%define ARRAY_SIZE 100
segment .data
Message db "Welcome ", 0
Message1 db "" ,0
Message2 db "Please enter doublewords for the first array. " , 0
Message3 db "Are there more inputs(1 (yes) or 0)? " , 0
Message4 db "Please enter doublewords for the second array.", 0
Message5 db "The first array is: " , 0
Message6 db " " , 0
Message7 db "The second array is: " , 0
segment .bss
runAgain resd 1 ; find primes up to this limit
firstArray resd ARRAY_SIZE ; the current guess for prime
secondArray resd ARRAY_SIZE
compar resd 1
segment .text
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
call print_nl ;printing a new line
mov eax, Message ;putting first message in eax for output
call print_string ;printing first message
call print_nl ;printing a new line
mov eax, Message1 ;putting 1st message in eax for output
call print_string ;printing 1st message
call print_nl ;printing a new line
mov eax, Message2 ;putting 2nd message in eax for output
call print_string ;printing 2nd message
call read_int ;reading in user input
mov [firstArray], ax ;storing input in a array
call print_nl ;print new line
mov eax, Message3 ;putting 3rd message in eax for output
call print_string ;printing 3rd message
call read_int ;reading int for new run
mov [runAgain], eax ;storing input in eax
while_first_Array: ; while ( runAgain <= 1 )
mov eax,[runAgain] ;moving runAgian to compar for the loop
cmp eax, 1 ;comparing to see if loop ends
mov [runAgain],0
mov eax, Message2 ;putting 2nd message in eax for output
call print_string ;printing 2nd message
call read_int ;reading in user input
mov [firstArray+4],ax ;storing input in array
call print_nl ;printing new line
mov eax, Message3 ;putting 3rd message in eax for output
call print_string ;printing third message
call read_int ;reading in input for loop check
mov [runAgain], eax ;storing in eax for loop check
jnbe end_first_Array ; use jnbe since numbers are unsigned
end_first_Array: ;end of loop
mov eax, Message4 ;putting 4th message in eax
call print_string ;printing fourth message
call print_nl ;printing a new line
while_Second_Array: ;while ( runAgain <= 1 ) for second array
mov eax,[runAgain] ;moving runAgian to compar for the loop
cmp eax, 1 ;moving runAgian to com
mov eax, Message2 ;putting 2nd message in eax for output
call print_string ;printing 2nd message
call read_int ;reading in user input
mov [secondArray+4],eax ;storing input in array
call print_nl ;printing a new line
mov eax, Message3 ;putting 3rd message in eax for output
call print_string ;printing third message
call read_int ;reading in input for loop check
mov [runAgain], eax ;storing in eax for loop check
jnbe end_Second_Array ; use jnbe since numbers are unsigned
end_Second_Array:
-
Same thing(s) you were doing wrong last time we spoke! :)
while_first_Array: ; while ( runAgain <= 1 )
mov eax,[runAgain] ;moving runAgian to compar for the loop
cmp eax, 1 ;comparing to see if loop ends
Okay, you've set the flags...
mov [runAgain],0
Dude! This doesn't even assemble!
mov eax, Message2 ;putting 2nd message in eax for output
call print_string ;printing 2nd message
call read_int ;reading in user input
mov [firstArray+4],ax ;storing input in array
Why ax? Why "firstArray + 4"... every time?
call print_nl ;printing new line
mov eax, Message3 ;putting 3rd message in eax for output
call print_string ;printing third message
call read_int ;reading in input for loop check
mov [runAgain], eax ;storing in eax for loop check
jnbe end_first_Array ; use jnbe since numbers are unsigned
Having set flags waaay back at the beginning of this section, you expect 'em to still be set? Well... Dr. Carter considerately preserves flags in his functions, and none of the instructions you use happen to set flags... so I quess they are... So you've compared "[runAgain]" to one, and you're going to jump if it's not below or equal. When will that be? (if the user misbehaves and enters 2 when you ask for 1 or 0, I guess) What happens if the jump is not taken?
end_first_Array: ;end of loop
Answer: you fall through into second_array... And at the end of that... you fall off the end of your program into the puckerbrush! By some mechanism I don't understand, after a few nops, this hits "call asm_main" (in main, presumably?), and we start off again with "Welcome". I'd expect this to just-plain-crash, and I have no idea why it's re-running the program, but that's what you're doing wrong.
I suggest you re-read (or maybe just read) Dr Carter's chapter on arrays. It's a handful, I'll give ya that! When I first(?) read it (not "in order"), I thought he was crazy, teaching 'em about arrays, and just now introducing the addressing mode required to do it. But... arrays are pretty much what the addressing mode is "good for", so I guess it's appropriate to introduce 'em together. Pay special attention to the example code!
Maybe I should take that back... his "array1.asm" uses that special version of "driver.c", and calls scanf directly. That complicates the situation somewhat. Scanf takes the address to store the integer as a parameter, so you're not doing "get the result, store it in an array" like you want...
Try this example instead:
;
; file: arraytest.asm
;
; for Linux:
; nasm -elf -d ELF_TYPE arraytest.asm
; gcc -o arraytest arraytest.o driver.c asm_io.o
;
; other OSen? RTFM
; http://www.drpaulcarter.com/pcasm
%include "asm_io.inc"
%define ARRAY_SIZE 10 ; enough for test purposes
;
; initialized data is put in the .data section
;
section .data
;
; These labels refer to strings used for output
;
prompt1 db "Please enter a number. ", 0
querry db "More to enter? (y/n)", 0
outmsg1 db "You entered ", 0
;
; uninitialized data is put in the .bss section
;
section .bss
;
; These labels refer to double words used to store the inputs
;
input1 resd ARRAY_SIZE
;
; code is put in the .text section
;
section .text
global asm_main
asm_main:
enter 0,0 ; setup routine
pusha
xor ecx, ecx ; element number
.top:
mov eax, prompt1 ; print out prompt
call print_string
call read_int ; read integer
; store it in "element ecx".
mov [input1 + ecx * 4], eax
inc ecx ; next element
cmp ecx, ARRAY_SIZE - 1
ja .show_em ; if we run out of space, quit and print 'em
.ask:
mov eax, querry
call print_string
call read_char ; flush trailing garbage from i/o buffer???
call read_char
cmp al, 'y'
je .top
cmp al, 'n'
jne .ask
;
; next print out result message as series of steps
;
.show_em:
mov eax, outmsg1
call print_string ; print out first message
; ecx still holds the count of elements we entered
xor ebx, ebx ; start with index zero
.more:
mov eax, [input1 + ebx * 4]
call print_int ; print out input1
mov al, ' ' ; (or other spacer)
call print_char
inc ebx ; next index into array
loop .more ; do 'em all
call print_nl ; print new-line
popa
mov eax, 0 ; return back to C
leave
ret
;------------------------------------------
Don't ask me why I had to call read_char twice. I can see why you were going for 0 or 1. I think maybe that "dump_line" routine needs to go into the regular "driver.c", and perhaps get called more often...
In any case, that should show you how to store an integer in an array, without them all being in the same place. Re-read that chapter anyway!
Best,
Frank