News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

New to Assembler

Started by magus841, May 03, 2010, 02:45:49 AM

Previous topic - Next topic

magus841

Hello everyone! This board seems very awesome and I am very happy that I found it.

I am taking my first Assembly Language course in college and I was having trouble with getting a program to work properly. I have the following code but it's not doing what I think it should. The whole program is supposed to figure out if an input number is prime or not and it's not working right as a whole, but one problem at a time, right?


INCLUDE Irvine32.inc
.data
test_Val dd 0
prompt db 'Input any integer. End with a -1', 0dh, 0ah
not_prime_prompt db 'The number is not prime.', 0dh, 0ah
prime_prompt db 'The number is prime.', 0dh, 0ah

.code
main PROC
     
    mov edx, offset prompt
    call WriteString


What happens is that when I call WriteString, all three of the prompts get output instead of the one I just moved into the edx register. Anyone know why this is occurring? I'm sorry if the answer's obvious. I'm really bad with assembly language but I really do want to learn it.

joemc

i don't have Irvine32.inc . It appears it comes with a book. I am unable to find it on google. Is it something you have the right to share?

Edit:
Well i am guessing WriteString is going to take a null terminated string in edx. Your string does not appear to have a 0 at the end of them. Just a guess though, i do not have the library.

try


INCLUDE Irvine32.inc
.data
test_Val dd 0
prompt db 'Input any integer. End with a -1', 0dh, 0ah,0
not_prime_prompt db 'The number is not prime.', 0dh, 0ah,0
prime_prompt db 'The number is prime.', 0dh, 0ah,0

.code
main PROC
     
    mov edx, offset prompt
    call WriteString

Gunner

each one of the strings need to be null terminated......0dh,0ah,00h
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

magus841

Ah yes, I actually do.

I was poking around Irvine32.inc and it seems to include two other files, SmallWin.inc and VirtualKeys.inc so I'll include those as well in the .zip.

joemc

Quote from: Irvine32.inc
WriteString PROTO      ; write null-terminated string to output
yep, does not appear to take size, and says it needs to be null terminated. Doesn't say that it takes it in edx, but i am assuming your book does.  ,0  or as gunner said ,00h should work.

magus841

Yes, it does ^.^ thank you.

Perhaps I can trouble you all for another answer to a question?

I'm using ReadInt now, which is from the same include file. It's supposed to read a 32-bit signed integer from the keyboard and return the value in the eax register. Then I'm taking that and moving it into test_Val (from my code above). And then I want to divide it by 1. So basically my code looks like this.


.data
test_Val dd ?
.code
call ReadInt
mov test_Val, eax
mov eax, 1
div test_Val


But at div test_Val my program ceases to function and breaks. and I'm not sure why? I might be using div incorrectly. Like I said I'm bad at this. If anyone wants to point out my mistake I'd appreciate it. :)

joemc

#6
Dividing by 1 should give you the same number you started with. I am sure you plan on dividing by something else eventually. :)
in your code you are dividing 1 by test_val which is not going to be an integer unless test_val is also a 1.

maybe
call ReadInt

mov test_Val, eax  ; just to store
mov edx,0          ; edit : added to fix code
mov ebx,1          ; hopefuly something other than 1 :lol
div ebx           



div only takes a general purpose register or memory location.

at this point eax will contain the quotient and edx the remainder.

I also had trouble with div and mul when i first saw them. 

edit:
and apparently still do :)

magus841

Okay I'm still having an issue. I changed it so that I'd be doing div test_Val where test_Val keeps getting larger and larger each time I go through the loop and the value I entered using ReadInt stays in the eax with push and pop. But the program still dies at the div instruction. My code: It's supposed to check if the number is prime or not.


INCLUDE Irvine32.inc
.data
test_Val dd 1
prompt db 'Input any integer. End with a -1', 0dh, 0ah, 00h
not_prime_out db 'The number is not prime.', 0dh, 0ah, 00h
prime_out db 'The number is prime.', 0dh, 0ah, 00h

.code
main PROC
     
    mov edx, offset prompt
    call WriteString
    call Crlf
   
A1:
    call ReadInt
    cmp eax, -1
    je done
   
    mov ecx, eax
   
Calculate:
    push eax
    div test_Val
    pop eax
    inc test_Val
    cmp edx, 0
    je not_prime
    loop Calculate
   
    mov edx, offset prime_out
    call WriteString
    jmp done
   
not_prime:
    mov edx, offset not_prime_out
    call WriteString
    jmp A1
   
done:
    ret

main ENDP

END main



It's not quite done yet. But I think I have the right idea? If I ever get a zero as the remainder, then the number can't be prime, right?

Edit: I keep getting an integer overflow error? Even if I am dividing 1 by 1.
I also tried doing something simple in an asm block in C++ code. Same error.

#include <iostream>
using namespace std;

int main(){

    _asm{
   mov ax, 1
   mov bx, 1
   div bx
   ret
    }

    return 0;
}



Am I just stupid?

joemc

sorry i did not explain right the first time :( i am new too. You are getting an overlow because there is probably some large number in edx.

try adding a
mov edx,0
before the div

div divides edx:eax by a integer in a register or memory location.
and the answer is quotient :eax remainder :edx

for your c version it would be dx:

#include <iostream>
using namespace std;

int main(){

    _asm{
           mov dx,0
   mov ax, 1
   mov bx, 1
   div bx
   ret
    }

    return 0;
}



magus841

Okay that helped. Thank you very much :D

Now I just have to make it run properly. I appreciate it :)

clive

Well all numbers are divisible by one and them self, so you need to specifically exclude those. ie Start by dividing by 2, and loop 2 less times, and checking that you input is greater than 2.

Something like

..
    call ReadInt
    cmp eax, -1
    je done

    or eax,eax ; eax = Zero
    jz done

    mov ecx, eax ; Loop counts

; We need to compare 2 less, because always divisible by 1 and self

    dec ecx
    jz  not_prime ; eax = 1

    dec ecx
    jz  prime ; eax = 2

    mov test_Val,2 ; [2 .. N-1]
   
Calculate:
    xor edx,edx
    push eax
    div test_Val
    pop eax
    inc test_Val
    cmp edx, 0
    je not_prime

    loop Calculate

prime:   
    mov edx, offset prime_out
    call WriteString
    jmp done
   
not_prime:
    mov edx, offset not_prime_out
    call WriteString
    jmp A1
   
done:
..


Or using ECX instead of your test_Val, counts down rather than up


..
    call ReadInt
    cmp eax, -1
    je done

    or eax,eax ; eax = Zero
    jz done

    mov ecx,eax ; Loop counts

; We need to compare 2 less, because always divisible by 1 and self

    dec ecx
    jz  not_prime ; eax = 1

    cmp ecx,1
    jz  prime ; eax = 2

    ; [2 .. N-1]
   
Calculate:
    xor edx,edx
    push eax
    div ecx
    pop eax
    cmp edx,0
    je not_prime

    dec ecx
    cmp ecx,1 ; stops at 1, not 0 like loop
    jnz Calculate

prime:   
    mov edx, offset prime_out
    call WriteString
    jmp done
   
not_prime:
    mov edx, offset not_prime_out
    call WriteString
    jmp A1
   
done:
..
It could be a random act of randomness. Those happen a lot as well.

dedndave

1 isn't considered to be a prime number, either   :bg

i understand that you are just starting out, but i thought i'd mention this anyways
testing for primes that way is kinda slow
if you google around or use the forum search tool, there are a number of faster techniques
you may not care about speed at this point, but it is good to know