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.
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
each one of the strings need to be null terminated......0dh,0ah,00h
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.
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.
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. :)
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 :)
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?
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;
}
Okay that helped. Thank you very much :D
Now I just have to make it run properly. I appreciate it :)
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:
..
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