NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: fliego on March 31, 2015, 05:07:41 PM
-
Hi!
User input num, then program have to print all prime numbers from 0 to n.
No errors through compile, but no any print info
Ubuntu x86, nasm
global _start
section .data
msg db "Hello"
section .bss
num resb 4
section .text
_start:
call input
mov eax,num
push eax
call isPrime
push edx
call print
call exit
exit:
mov eax,1
mov ebx,0
int 0x80
ret
print:
push ebp
mov ebp,esp
mov ecx,[ebp+8]
mov eax,4
mov ebx,1
mov edx,4
int 0x80
pop ebp
ret
input:
push ebp
mov ebp,esp
mov eax,3
mov ebx,0
mov ecx,num
mov edx,4
int 80h
pop ebp
ret
isPrime:
push ebp
mov ebp,esp
mov eax,[ebp+8]
mov edx,0
cmp eax,0
je .mEx
cmp eax,1
je .mEx
cmp eax,2
je .mExTwoOrThree
cmp eax,3
je .mExTwoOrThree
mov ebx,2
mov ecx,eax
shr ecx,1
.mMain:
push eax
mov edx,0
div ebx
pop eax
cmp edx,0
jne .mZR
mov edx,0
jmp .mEx
.mZR:
cmp ebx,ecx
je .mEx
inc ebx
jmp .mMain
.mExTwoOrThree:
mov edx,1
.mEx:
pop ebp
ret
-
Hi fliego,
Thanks for joining us.
Think about what you're actually asking to have printed. Your "print" routine expects the address of four characters to print on the stack. I'm not sure what "isPrime" returns in edx (zero or non-zero?), but it isn't likely to be a valid address of a string to print. So no output.
We can't really input or print "numbers". We read characters (hopefully representing a number), and need to convert that to a number before we can use it for anything. Likewise when we get a number (some prime less than n), we need to convert that to characters we can write.
There are different ways to do that. "Just call scanf/printf" is easy - I consider it "overkill" just to read/write an integer. There are a number of libraries that include such routines written in assembly. Our user "stressful" has recently posted such a library (not in the form of a literal "library") that looks quite nice:
http://forum.nasm.us/index.php?topic=2062.0
Or you can write your own routines to convert text-to-number and number-to-text. I consider this "a good exercise", but it's been done before... It's about the most frequently asked question of all time, so you should be able to find plenty of examples to "go by" (or swipe). Hmmm... here's an example that seems to do exactly what you want (although more complicated, perhaps):
http://forum.nasm.us/index.php?topic=1289.msg5158#msg5158
In any case, you need to pass "print" the address of some text. Your "input" routine gets text, and you're passing that to "isPrime". That probably isn't going to work as intended either. If you continue to have trouble, let us know where you're stuck, and we'll try to help.
Best,
Frank
Edit: here's some more discussion of the subject:
http://forum.nasm.us/index.php?topic=1514.msg6228#msg6228
-
I remember, one time I taught a class of girls about prime numbers. When girls get to learn about prime numbers they often get a chance to teach it away also. After so many years of being a teacher, you'll notice that when girls get to know about boystuff, they often also compete with the opposite sex. It's unmistakable. I did not ever want to have anything to do with that, so I asked them to please leave me out of it.
When that being said, one of the things I like and don't like about nasm and fasm is that nasm is so damn liberal in its design. fasm is so narrowed down and almost "closed up". fasm, to me, is like fascism. It seems as if the author of it want it to evolve into a hll language.
-
Thank you very much, Frank! :}
Seems like program do what I desided it to:
%include "/home/student/stud_io.inc"
section .bss
digit resb 1
section .data
new_line db 10,13
section .text
global _start
_start:
print_string "N = "
call read_number
mov ecx,eax
mov eax,1
main_loop:
inc eax
cmp eax,ecx
jnl exit
mov ebx,2
is_prime:
cmp eax,ebx ; haltura
je print_prime
push eax
xor edx,edx
div ebx
pop eax
test edx,edx
jz not_prime
inc ebx
jmp is_prime
not_prime:
jmp main_loop
print_prime:
push eax
call print_number
print_string " "
jmp main_loop
exit:
mov eax,4
mov ebx,1
mov ecx,new_line
mov edx,2
int 80h
syscall_exit 0
read_number:
xor eax,eax
mov ebx,10
mov [digit],byte 0x30
.read_digit:
mul ebx
add eax,[digit]
sub eax,0x30
call read_digit
cmp [digit],byte 0xA
jne .read_digit
ret
read_digit:
pusha
mov eax,3
mov ebx,0
mov ecx,digit
mov edx,1
int 80h
popa
ret
print_number:
mov eax,[esp + 4]
pusha
mov ebx,10
xor ecx,ecx
.push_digit:
xor edx,edx
div ebx
push dx
inc ecx
test eax,eax
jnz .push_digit
.print_digit:
pop ax
call print_digit
loop .print_digit
popa
ret
print_digit:
pusha
mov [digit],al
add [digit],byte 0x30
mov eax,4
mov ebx,1
mov ecx,digit
mov edx,1
int 80h
popa
ret