### Author Topic: traversing through a Register  (Read 3956 times)

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### traversing through a Register
« on: June 29, 2014, 09:35:26 PM »
I have been trying to add individual digits together in a register for example if I have a number 423 then I would add them like so : 4 + 2 + 3 = 9 but it isnt giving me the desired result when I execute this code:
Code: [Select]
`mov qword[x_number], r8mov r8, x_number;mov the adress into r8add r8, 80mov byte [r8], 0;put a zero after the numbersub r8, 80xor rcx, rcx;clear out rcx for use;add individual digits together.forLoop2: add cl, byte[r8] add r8, 1;get ready for the next number cmp byte[r8], 0;if this digit is equal not equal to zero then jump back to the top jne .forLoop2 ;print out the result stored in rcx mov qword[x_number], rcx mov r8, qword[x_number] call itoa ;print out a new Line mov rsi, newLine mov rdx, newLine_L mov rax, 1 mov rdi, 1 syscall `I think its is because of the way I am traversing through the register but I have no Idea how I can fix it

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2364
• Country:
##### Re: traversing through a Register
« Reply #1 on: June 29, 2014, 10:42:00 PM »
Hmmm... what have you done before the code you show?
Code: [Select]
`mov r8, 432 ; decimalmov r8, 432h ; or 0x432 or \$432 - hexmov r8, "432" ; ascii`?
None of these is going to put a digit in a byte.

Code: [Select]
`mov r8, 4<<16 | 3<<8 | 2`This one might give you the result you seem to expect.

I'm confused!

Best,
Frank

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #2 on: June 30, 2014, 04:05:23 AM »
Well I am trying to get a number with  a power like if the user enters 2 and 15 it would turn out as 2^15 or 32768 and I have tested it to see if it works I then print the value 32768 push it onto the stack then pass it to r8 and move the actual number to it here is my number to it I didn't post the full code because i didn't think it was relevant but here it is:
Code: [Select]
`section .data PowerMsg: dq "Input a power",10 PowerMsg_L: equ \$ - PowerMsg newLine: dq "",10  newLine_L: equ \$ - newLinesection .bss power resq 255 number resq 255section .text%include "functions.asm"global _start:_start: mov rax, 1 mov rdi, 1 mov rdx, MSG_L mov rsi, MSG syscall mov rax, 0; mov rdi, 0 mov rdx, 255 mov rsi, number syscall mov rax, 1 mov rdi, 1 mov rdx, PowerMsg_L mov rsi, PowerMsg syscall mov rax, 0 mov rdi, 0 mov rdx, 255 mov rsi, power syscall mov r8, power call atoi mov rcx, rax; the power push rcx mov r8, number call atoi pop rcx call PowerSum mov rax, 60 mov rdi, 0 syscallretPowerSum:;power is passed in rcx;number is passed in raxpush rbxmov rbx, rax.forLoop:;calculates the n^x power xor rdx, rdx mul rbx dec rcx cmp rcx, 1  jne .forLoopmov qword[x_number], raxpush raxmov r8, qword[x_number]call itoamov rsi, newLinemov rdx, newLine_Lmov rax, 1mov rdi, 1syscallxor r8, r8pop r8;mov the number into r8pop rbx;restore rbxmov qword[x_number], r8mov r8, x_number;mov the adress into r8add r8, 80mov byte [r8], 0;put a zero after the numbersub r8, 80xor rcx, rcx;clear out rcx for use;add individual digits together.forLoop2: add cl, byte[r8] add r8, 1;get ready for the next number cmp byte[r8], 0;if this digit is equal not equal to zero then jump back to the top jne .forLoop2 ;print out the result stored in rcx mov qword[x_number], rcx mov r8, qword[x_number] call itoa ;print out a new Line mov rsi, newLine mov rdx, newLine_L mov rax, 1 mov rdi, 1 syscall .done:ret`
« Last Edit: June 30, 2014, 04:07:07 AM by Anonymous »

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2364
• Country:
##### Re: traversing through a Register
« Reply #3 on: June 30, 2014, 05:54:02 AM »
You may need to refresh my memory on what your "itoa" does. It prints the ascii decimal representation of the number, right?... and leaves it in your buffer as a zero-terminated string? So...

2 - you enter the number
15 - you enter the power
32768 - you print the result
266 - you print the sum of the ascii characters
But wait! That's going to overflow cl, so:
10?

What does it do? If you expect it to print 26, you're going to have to subtract '0' from each character before you add it to cl...

I'm no less confused than before.

I think I can say with some confidence that your strings ought to be declared as "db" not "dq", but I doubt if that's your problem...

Best,
Frank

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #4 on: June 30, 2014, 08:38:52 PM »
Well the result of my itoa is not stored in any register it just prints it the original integer is still in rax which is what I passed it in so I don't know why it is giving me 128 instead of 26

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #5 on: July 02, 2014, 01:16:43 AM »
If it helps I am doing project euler problem 16

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2364
• Country:
##### Re: traversing through a Register
« Reply #6 on: July 02, 2014, 03:14:19 AM »
Oh.

What is the sum of the digits of the number 2^1000?

That's easy. 1. That's my answer and I'm sticking to it. They don't say decimal digits, although that's obviously the intent. Decimal would be an absolutely insane way to represent that number. Who would do such a thing? Oh, Euler...

First thing to do would be to calculate 2^1000, I guess - unless we just represent it as binary... Your routine to do 2^15 is not going to work for 2^1000! You'll need a "bignum" routine of some sort, I would think. But gotta start somewhere!

128, you say? That seems a strange result. I've gotta get that 64-bit machine running again so I can follow along better. Maybe soon...

Best,
Frank

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #7 on: July 02, 2014, 08:45:06 PM »
I found another way to add the individual digits but I am still curious how you could grab the individual digits and add them directly and also I have been looking into Big numbers and How to handle them and they look extremely complex, One thing I know is that I have to find a way to store that big number into multiple registers like RBX:RCX and then how to manipulate them so I can add the individual digits here is a snippet of where I changed the code in the second forloop :
Code: [Select]
`forLoop2: div rcx;divide by 10 add r8, rdx;add the remainder to r8 xor rdx, rdx;clear out rdx cmp rax, 0;if rax is not equal to zero then jump back to forLoop2jne .forLoop2`

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #8 on: July 02, 2014, 09:13:14 PM »
I have commented out  my old code now to test if the number is too big but I have no Idea if I am going in the right direction with the "Bignum" I am trying to create, here it is
EDIT: As I have researched how to implement a Bignum I found this algorithm which I have tried to implement here but to no avail, it just prints out random numbers to me it looks like
Code: [Select]
`PowerSum:;power is passed in rcx;number is passed in raxmov r12, raxxor r8, r8xor r9, r9xor r10, r10mov r10, r10xor r11, r11xor rcx, rcx;xor rsp, rsp.forLoop:;calculates the n^x power  xor rdx, rdx;the remainder mul r12;what we are multiplying by add rax, r11 xor r11, r11;clear out the carry variable dec rcx;counter cmp rax, 10;if rax is not greater than or equal to 10 then jump to .next jnge .next add r11, 10 sub rax, r11 push rax;save the variable push rcx;save the counter printNum rax pop rcx;restore the counter pop rax;store the variable .next: cmp rcx, 1 jne .forLoopret`
« Last Edit: July 08, 2014, 05:33:19 AM by Anonymous »

#### Anonymous

• Jr. Member
• Posts: 78
• Country:
##### Re: traversing through a Register
« Reply #9 on: July 08, 2014, 06:07:55 AM »
Is there anyone that could help me with implementing a Bignum in my code I have been looking all over and I have found nothing so far and I think I have tried everything or at least everything I can think of.

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2364
• Country:
##### Re: traversing through a Register
« Reply #10 on: July 08, 2014, 08:02:48 AM »
Well... no. This is a 32-bit version of what I think needs to be done. IT IS NOT CORRECT! I'm getting 1367 and the correct answer is apparently 1366. Obviously allowing 64 bits for the sum was overkill. (I tried it before looking up the answer) This can be simplified quite a lot. Finding my off-by-one error is left as an exercize for the student.

Best,
Frank

Code: [Select]
`global _start; purpose: attempt to calculate the sum; of decimal digits in 2^1000 (euler problem 16); nasm -f elf32 prog.asm; ld -o prog prog.o -m elf_i386section .data; 2^1000 = 125 bytes?    number db 80h    times 124 db 0end_number:section .bss    sum_of_digits resd 2 ; enough?    asciibuff resb 80h; do we want to try to print this puppy?section .text_start:    mov ebx, 10    mov esi, number    xor edx, edxtop:    mov eax, [esi]    div ebx    mov [esi], eax    add esi, 4    cmp esi, end_number    jb top    add [sum_of_digits], edx    adc dword [sum_of_digits + 4], 0    mov esi, number    xor edx, edxcheck_zeros:    cmp dword [esi], 0    jne top    add esi, 4    cmp esi, end_number    jb check_zeros    mov eax, [sum_of_digits]    mov edx, [sum_of_digits + 4]    mov edi, asciibuff    call u64toda    mov ecx, asciibuff    mov edx, 80 ; ?    mov ebx, 1    mov eax, 4    int 80h    mov eax, 1    xor ebx, ebx    int 80h;--------------------------------------------------------------; u64toda - converts (64 bit) integer in edx:eax; to (comma delimited) decimal representation in; asciiz ( & "\$") terminated string in buffer pointed to by edi;-----------------------------------------------------------------u64toda:                pusha                mov ebx, edx     ; stash high dword                mov esi,0Ah      ; prepare to divide by 10                xor ecx, ecx     ; zero the digit count                jmp highleft     ; check is high word 0 ?highword:                xchg eax,ebx    ; swap high & low words                xor edx,edx     ; zero edx for the divide!                div esi         ; divide high word by 10                xchg eax,ebx    ; swap 'em back                div esi         ; divide low word including remainder                push edx        ; remainder is our digit - save it                inc ecx         ; count digitshighleft:                or ebx,ebx                jnz highwordlowleft:                xor edx,edx          ; zero high word                div esi              ; divide low word by 10                push edx             ; our digit                inc ecx              ; count it                or eax,eax           ; 0 yet ?                jne lowleft                cmp ecx, byte 4      ; commas needed ?                jl write2buf         ; nope                xor edx,edx            ; zero high word for divide                mov eax,ecx            ; number of digits                mov ebx,3                div ebx                mov esi,edx            ; remainder = number digits before comma                test edx,edx                jnz write2buf        ; no remainder?                mov esi,3             ; we can write 3 digits, then.write2buf:                pop eax              ; get digit back - in right order                add al,30H           ; convert to ascii character                stosb                ; write it to our buffer                dec esi               ; digits before comma needed                jnz moredigits       ; no comma needed yet                cmp ecx,2             ; we at the end?                jl moredigits        ; don't need comma                mov al,','           ; write a comma                stosb                mov esi,03h           ; we're good for another 3 digitsmoredigits:                loop write2buf       ; write more digits - cx of 'em                mov al,00h           ; terminate buffer with zero                stosb popa                ret;-------------------------------------------------------------`

#### Frank Kotler

• NASM Developer
• Hero Member
• Posts: 2364
• Country:
##### Re: traversing through a Register
« Reply #11 on: July 08, 2014, 12:54:28 PM »
Apparently I wasn't representing 2^1000 correctly.
Code: [Select]
`; 2^1000 = 125 bytes?    number dd 100h    times 31 dd 0end_number:`
Now it goes 1366.

Best,
Frank