The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jwill22 on January 27, 2011, 09:35:29 PM

Title: Hey I need some help with this assembly language assignment
Post by: jwill22 on January 27, 2011, 09:35:29 PM
OK let me say first that I'm using Kip Irvine's book,"Assembly Language for x86 processors", and I'm using Microsoft Visual c++ 2010. OK I need to (1). fill an array with 50 random integers;(2) loop through the array, displaying each value, and count the number of negative values;(3) after the loop finishes, display the count. I'm having a problem with counting the negative numbers.  This is what I got so far.
INCLUDE Irvine32.inc


.data
array1 SWORD 50  DUP(0)
count SWORD 0



.code
main PROC
mov ecx,50
mov esi OFFSET array1
mov esi,eax
mov ebx,0

eloop:

add esi,2
call Random32
call WriteInt
mov esi,eax
loop eloop

   
exit

    main ENDP
    END main

Title: Re: Hey I need some help with this assembly language assignment
Post by: jj2007 on January 27, 2011, 09:52:15 PM
Quote from: jwill22 on January 27, 2011, 09:35:29 PM

call Random32
mov [esi], ax
call WriteInt


1. We don't use Irvine's lib much here, but normally a function such as WriteInt will overwrite eax. Check also if ecx is preserved, otherwise you need a push ecx/pop ecx pair around the calls.
2. So you must save it to memory ( [esi], not esi ) before WriteInt, and as ax because your array is word sized.
3. You do know the no homework rule, right? But since you are pretty advanced, and posted your own code, we'll make an exception.

Welcome to the Forum :bg
Title: Re: Hey I need some help with this assembly language assignment
Post by: jwill22 on January 27, 2011, 09:55:09 PM
Yes i did read about the homework rule..and believe me i don't want anybody to spoonfeed me anything..i'm too competitive for that, but thanks for that..I'm about to try that right now :bg :bg :bg :bg
Title: Re: Hey I need some help with this assembly language assignment
Post by: jj2007 on January 27, 2011, 10:10:56 PM
by far the best way of learning is to run your executable with OllyDebug. The F7 and F8 key will be your friends. Check especially the content of eax, ecx, edx after calls.
Check also here (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm) the "register gets trashed" trap.
Title: Re: Hey I need some help with this assembly language assignment
Post by: dedndave on January 28, 2011, 12:30:28 AM
Kip's library functions tend to preserve all registers, unless something is returned in them
Title: Re: Hey I need some help with this assembly language assignment
Post by: jwill22 on January 28, 2011, 01:44:29 AM
Ok what do you mean by preserve :eek ? by the way I'm still not getting it..I'll post what I have in a lil bit
Title: Re: Hey I need some help with this assembly language assignment
Post by: MichaelW on January 28, 2011, 02:45:35 AM
Preserving a register means essentially preserving the value of the register around code that uses the register. For example, this is the code I have for the Irvine32 Random32 procedure:

  push  edx
  mov   eax, 343FDh
  imul  seed
  add   eax, 269EC3h
  mov   seed, eax    ; save the seed for the next call
  ror   eax,8        ; rotate out the lowest digit (10/22/00)
  pop   edx

  ret


EDX is used by the imul instruction, so to preserve it a copy of its value is pushed onto the stack at procedure entry, and the copy is popped off the stack and into the EDX register before the procedure returns. So this procedure preserves all registers, other than the EAX register that it uses to return the random number.
Title: Re: Hey I need some help with this assembly language assignment
Post by: jwill22 on January 28, 2011, 04:27:00 AM
Ooohhhh....oookkkk

here's what I have though. I'm trying to figure out how to loop this so it can move to the next element in the array each time it loops

INCLUDE Irvine32.inc


.data
array1 SDWORD 50  DUP(?)
ptr3 SDWORD array1

.code
main PROC
mov ecx,50
mov esi, OFFSET array1-4 


loop1:
add esi,4
call Random32
call WriteInt
mov [esi],eax
call Crlf
loop loop1

mov ecx,50
step:
add esi,4
mov esi,ptr3
mov eax,[esi]
call WriteInt
loop step









Every time It loops at the bottom it just displays the 1st number in [esi]...I know I have to add 4 to [esi] each time to move to the next element, but I'm having a problem with trying to do that. Any Suggestions?
Title: Re: Hey I need some help with this assembly language assignment
Post by: jj2007 on January 28, 2011, 06:14:58 AM
Since I can't test it with Irvine's library, here an example in MB. It works perfectly:
...
negative: -48
negative: -19

29 positive and 21 negative numbers found

Quoteinclude \masm32\MasmBasic\MasmBasic.inc   ; download (http://www.masm32.com/board/index.php?topic=12460)
.data
ctPos   dd ?
ctNeg   dd ?
array1   SDWORD 50  DUP(?)
ptr3   SDWORD array1      ; what is the role of this one??

   
Init
   Rand()[/color]   ; initialise random generator
   mov ecx, 50
   mov esi, OFFSET array1-4   ; put esi on start of array
loop1:
   add esi, 4
   mov eax, Rand(100)   ; generate a random number between 0 and 100
   sub eax, 50   ; transform to -50...+50
   mov [esi], eax
   loop loop1

   mov ecx, 50
   mov esi, OFFSET array1-4   ; reset esi to start of array
step:
   add esi, 4
   mov eax, [esi]
   test eax, eax
   .if Sign?
      Print Str$("negative: %i", [esi]), CrLf$
      inc ctNeg
   .else
      Print Str$("positive: %i", [esi]), CrLf$
      inc ctPos
   .endif
   loop step

   Inkey Str$("\n%i positive ", ctPos), Str$("and %i negative numbers found", ctNeg)
   
Exit
end start
Title: Re: Hey I need some help with this assembly language assignment
Post by: jwill22 on January 28, 2011, 08:12:55 AM
Thanks so Much..!! But I still didn't get the final product correct :( :( :( I'm just going to e-mail my instructor what i got. I feel kinda dumb :'(
Here's my code

INCLUDE Irvine32.inc


.data
array1 SDWORD 50  DUP(?) ;allocate room for array
;ptr3 SDWORD array1
count DD 0 ;count variable
deduct dd 0 ;deduct variable

.code
main PROC
mov ecx,50 ;move 50 to loop counter
mov esi, OFFSET array1-4 ;point to the array


loop1:
add esi,4 ;point to first element
call Random32 ;generate random 32 bit integer
call WriteInt
mov [esi],eax ;mov integer to memory
call Crlf ;create a new line
loop loop1

mov ecx,50 ;mov 50 to loop counter
mov esi,OFFSET array1-4 ;point to array
mov ebx,0
step:

add esi,4 ;point to element
mov eax,[esi] ;mov 1st element in memory to eax
cmp eax,0 ;compare eax to 0
.if (eax < 0)
inc count

.else
dec deduct
.endif



loop step

mov eax,count ;mov the count to eax
call WriteInt ;write number to screen












   
exit

main ENDP
END main



Man I tried.....
Title: Re: Hey I need some help with this assembly language assignment
Post by: japheth on January 28, 2011, 08:48:41 AM
Quote from: jwill22 on January 28, 2011, 08:12:55 AM
Man I tried.....

You'll have to tell Masm that the register is supposed to contain a SIGNED value:


.if ( sdword ptr eax < 0)
Title: Re: Hey I need some help with this assembly language assignment
Post by: dedndave on January 28, 2011, 09:03:58 AM
the code you have works, except that you are not incrementing the index into the array with each loop pass
mov [esi],eax      ;mov integer to memory
add esi,4          ;point to next array element
Title: Re: Hey I need some help with this assembly language assignment
Post by: jj2007 on January 28, 2011, 12:10:27 PM
Quote from: dedndave on January 28, 2011, 09:03:58 AM
the code you have works, except that you are not incrementing the index into the array with each loop pass
mov [esi],eax      ;mov integer to memory
add esi,4          ;point to next array element


Dave,

He uses mov esi, OFFSET array1-4, so the add esi, 4 is in the right position.

The eax<0 issue already flagged by Japheth is more serious (link (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm)):

Quotemov eax, -1
.if eax<0
    MsgBox 0, "Eax is less than zero", "Hi", MB_OK
.else
    MsgBox 0, "Surprise, surprise: eax is NOT less than zero", "Hi", MB_OK
.endif

The reason is simple: Registers are by definition unsigned integers. After a mov eax, -1, the register contains the
value 0FFFFFFFFh, decimal 4294967295 - and that is indeed a number way above zero. To achieve what you want
with .if eax<0, use .if sdword ptr eax<0 - this ensures that the register will be interpreted as a signed integer.
Title: Re: Hey I need some help with this assembly language assignment
Post by: dedndave on January 28, 2011, 01:45:45 PM
my mistake   :P
Title: Re: Hey I need some help with this assembly language assignment
Post by: brethren on January 28, 2011, 04:47:25 PM
INCLUDE Irvine32.inc

ARRAYSIZE = 50

.data
msg BYTE " negative values found.", 13, 10, 0
buffer SDWORD ARRAYSIZE DUP(0)
counter DWORD 0

.code
main PROC
call Randomize

;part 1 - fill array with random numbers
mov ecx, ARRAYSIZE
mov esi, OFFSET buffer
L1:
call Random32
mov [esi], eax
add esi, TYPE buffer
loop L1

;part 2 - loop through the array, display each value, count negative numbers
mov esi, OFFSET buffer
mov ecx, ARRAYSIZE
L2:
mov eax, [esi]
cmp eax, 0
jge @F
inc counter
@@:
call WriteInt
call Crlf
add esi, TYPE buffer
loop L2

;part 3 - Display the count
mov eax, counter
call WriteDec
mov edx, OFFSET msg
call WriteString

exit
main ENDP
END main



that'll do the job but make sure you understand it! if theres anything you don't understand feel free to ask

btw run it through a debugger :wink just change the value of ARRAYSIZE to say, 5, then trace your way through the program. then you'll see how it works
Title: Re: Hey I need some help with this assembly language assignment
Post by: qWord on January 28, 2011, 06:17:31 PM
isn't there the need to preserver ECX when calling  the functions Random32 and WriteInt?
Title: Re: Hey I need some help with this assembly language assignment
Post by: brethren on January 28, 2011, 06:53:58 PM
Quote from: qWord on January 28, 2011, 06:17:31 PM
isn't there the need to preserver ECX when calling  the functions Random32 and WriteInt?

no, internally all procs in irvine32.lib push/pop any registers they use (except for a return value in eax, of course :P)

heres one example
QuoteWriteInt PROC
;
; Writes a 32-bit signed binary integer to the console window
; in ASCII decimal.
; Receives: EAX = the integer
; Returns:  nothing
; Comments: Displays a leading sign, no leading zeros.
; Last update: 7/11/01
;-----------------------------------------------------
WI_Bufsize = 12
true  =   1
false =   0
.data
buffer_B  BYTE  WI_Bufsize DUP(0),0  ; buffer to hold digits
neg_flag  BYTE  ?

.code
   pushad
   CheckInit

   mov   neg_flag,false    ; assume neg_flag is false
   or    eax,eax             ; is AX positive?
   jns   WIS1              ; yes: jump to B1
   neg   eax                ; no: make it positive
   mov   neg_flag,true     ; set neg_flag to true
        .....
Title: Re: Hey I need some help with this assembly language assignment
Post by: jwill22 on February 02, 2011, 01:15:21 AM
 :bg :bg :bg I'm sorry I didn't get back to u guys sooner. I had to do a little surgery on my laptop, but I'm alright now. Thanks to everyone, I think I understand now. I really appreciate it. :U