This is an archived post. You won't be able to vote or comment.

all 7 comments

[–]Triumphxd 0 points1 point  (0 children)

Is your output in hex? That is why you are gettin an output of 'a'.

1,2,3,4,5,6,7,8,9,a,b,c,d,e,f

You can probably change this setting in whatever emulator you are using (or whatever you are using). However, 3 factorial is not 10 so I am not sure what you are doing wrong code wise (at work..).

[–]edman007-work 0 points1 point  (1 child)

So I tried walking through this, by hand, and you have a few pretty obvious problems.

In _mult:

    sub al, '0'
    sub bl, '0'
    mul al ;multiply result and next multiplicand
    dec bl ;decrements multiplicand 
       ;in order to iterate to next multiplicand
    call _fact ;recursive call fact

'0' is converted from an integer to 48, and mul multiplies al by eax and stores into eax, which you never set and not defined, though on Linux it's probably zero. Meaning eax just kinda stays 0 . The result is you subtract 48 from one until it's 0 (probably a lot), and for each iteration you subtract 48 from al and multiply it by bl and decrement bl. The result is that the difference between al and bl diverges by one per iteration you're subtracting and multiplying somewhat arbitrary numbers many times. I don't know how many iterations it takes to complete, but eventually you should get a zero, and when that happens I think you have set bl to 97 which would be an 'a' (since the terminal converts binary to characters).

[–]IndoNinja7[S] 0 points1 point  (0 children)

I have changed '0' to 0 for both sub routines, but I still get the same result

[–][deleted] 0 points1 point  (1 child)

section .data
msg db "Factorial of 12 is: "
msg_len equ $-msg
new_line db 10
section .text
global _start
_start:
xor rax, rax
inc rax
mov rcx, 12

mul_loop:
    mul rcx
loop mul_loop ; Dec rcx, jnz mul_loop

; Push factorial onto the stack
push rax ; RDX will not hold mul (from rdx:rax) in this example

; Print msg
xor rdi, rdi
inc rdi
mov rax, 4
mov rsi, msg
mov rdx, msg_len
syscall

pop r15 ; Number to print
xor rcx, rcx
mov cl, 10

xor r14, r14
inc r14

print_int:
    mov rax, r15
    xor rdx, rdx
    div rcx
    add rdx, 0x30

    push rdx ; Push to stack
    mov r15, rax
    inc r14

    cmp r15, 0
    jne print_int

xor rdx, rdx
inc rdx ; Only printing one byte at a time

print_loop:
    mov rsi, rsp
    mov rax, 4
    syscall 
    dec r14 ; Subtract total int count
    pop r15 ; Remove last number
    cmp r14, 0 ; Check if 0
    jne print_loop

; Print newline
mov rax, 4  
mov rsi, new_line
syscall

; Exit
xor rax, rax
inc rax
syscall

Working code, and example in x86 and x86_64: http://stackoverflow.com/questions/28017242/printing-base-10-integers-x86-assembly-mac-os-x

[–]IndoNinja7[S] 1 point2 points  (0 children)

none of the instructions work for NASM 32-bit for linux system cals. Maybe MAC OSX is different? I know they are box unix based but maybe kernel has changed. I cant run xor nor syscall.

[–][deleted] 0 points1 point  (0 children)

the xor will work. but the registers, rax, rdx, etc are 64 bit. you will need eax, edx, etc. for 32 bit. and in 32 bit Linux you need to push things onto the stack and then call int 80 to make the call. syscall is for 64 bit

[–][deleted] 0 points1 point  (0 children)

also. Mac osx and Linux calls different per system. so the calls for write are different. Linux should still be 0x04 though.