# NASM - The Netwide Assembler

## NASM Forum => Programming with NASM => Topic started by: ZimbuTheMonkey on March 29, 2014, 01:10:19 AM

Title: My sum is wildly off, I can't figure out why
Post by: ZimbuTheMonkey on March 29, 2014, 01:10:19 AM
Hello,

For an assignment, I have to compute the average of 10 numbers. I had it summing into a buffer correctly, but then I changed something and it no longer works (the sum is of order of magnitudes incorrect).

https://www.dropbox.com/s/pt8rqhkznaiuqjl/assign1.asm

There's the entire thing. I could use some help understanding where it's going wrong.

Thanks!

EDIT: So just with testing (printing out values in EAX), both get_num and print_num functions are working just fine. For example, if I input a 2, and add the value of 50 to eax and then call print_num, the output is 52.
Title: Re: My sum is wildly off, I can't figure out why
Post by: Frank Kotler on March 29, 2014, 04:57:34 AM
Your "total" is too small. You've reserved only two bytes, and put eax into it, overwriting your InputBuffer. Make it "resd 1". There may be more (only getting 9 numbers?), but that's what I see so far...

Best,
Frank

Title: Re: My sum is wildly off, I can't figure out why
Post by: ZimbuTheMonkey on March 29, 2014, 12:55:48 PM
That worked, thanks!

I had it at 2 because I figured 990 would be the maximum value it would ever have stored.

As for the loop, it's getting 10 numbers.
Title: Re: My sum is wildly off, I can't figure out why
Post by: Frank Kotler on March 29, 2014, 01:57:52 PM
Well 990 would fit in two bytes, but you'd have to use ax, not eax. I don't suggest you do this.

For your current problem: [numlist + ecx  * 4], not * 32. You want number of bytes, not bits. The "scale" can only be 1 (default), 2, 4, or 8.

One of us is having a problem counting to 10! Easily fixed, in any case.

Best,
Frank

...so other people can see it...
Code: [Select]
`section .data ; Welcome message wellmsg db "This program will compute the average of 10 2-digit numbers.",0xA wellmsglen equ \$-wellmsg askmsg db "Enter number: " askmsglen equ \$-askmsg section .bss numlist: resb 10 ; list of our numbers total: resd 1 ; to store the sum of the 10 numbers inputBufferSize equ 3 ; three characters (num1, num2 and enter key) inputBuffer resb inputBufferSize inputBufferEnd: outputBufferSize equ 10 outputBuffer resb outputBufferSize outputBufferEnd: section .text global _start    _start: ; print welcome message once mov eax, 4 mov ebx, 1 mov ecx, wellmsg mov edx, wellmsglen int 0x80 ; loop to run 10 times to read input and store number mov ecx, 0 prompt: ; store count push ecx ; prompt message mov eax, 4 mov ebx, 1 mov ecx, askmsg mov edx, askmsglen int 0x80 ; get input number call get_num add [total], eax pop ecx inc ecx cmp ecx, 9 jne prompt    mov eax, [total]    call print_num ;exit mov eax, 1 mov ebx, 0 int 0x80 get_num: ; input into buffer mov eax, 3 mov ebx, 0 mov ecx, inputBuffer mov edx, inputBufferSize int 0x80 ; eax = length of string ; make esi the start of the string mov esi, inputBuffer ; make edi the end of the string mov edi, inputBuffer add edi, eax dec edi mov eax, 0get_num_loop: mov edx, 10 mul edx ; edx:eax = eax * operand mov edx, 0 mov dl, [esi] sub dl, 0x30 inc esi add eax, edx cmp esi, edi jne get_num_loop ret ; eax = inputed value print_num: ; point to the end of the buffer mov edi, outputBufferEnd print_num_loop: ; move one character left dec edi ; set up division mov edx, 0 mov ebx, 10 div ebx ; eax = edx:eax / ebx, remainder in edx ; put the remainder on the buffer add dl, 0x30 ; make it ASCII first mov [edi], dl ; if after the above division, eax != 0, continue to loop, otherwise exit the loop cmp eax, 0 jne print_num_loop ; set up registers and make system call mov eax, 4 mov ebx, 1 mov ecx, edi mov edx, outputBufferEnd sub edx, edi int 0x80 ret`

Title: Re: My sum is wildly off, I can't figure out why
Post by: ZimbuTheMonkey on March 29, 2014, 04:45:23 PM
EDIT: Got it, though I'm not sure if it's the smartest way to do it:

Code: [Select]
` ; print welcome message once mov eax, 4 mov ebx, 1 mov ecx, wellmsg mov edx, wellmsglen int 0x80 call print_newline ; loop to run 10 times to read input and store number mov ecx, 0 prompt: ; store count push ecx ; prompt message mov eax, 4 mov ebx, 1 mov ecx, askmsg mov edx, askmsglen int 0x80 ;numbered prompt (store loop iteration + 1 in EAX, then print it) pop ecx push ecx mov eax, ecx inc eax call print_num call print_colon call print_space`
Yeah, I'm silly. I figured it after thinking to myself "why exactly am I scaling by 32 again?". :p

So the thing is done and operational. However, at the moment this is how the user will see the looped prompt:

Enter number: 11
Enter number: 28
Enter number: 19... etc.

But I want it to be:

Enter number #1: 11
Enter number #2: 28... etc.

I'm trying to use the ECX loop counter in there somehow to be the numbered part of it, but I am failing miserably.
Title: Re: My sum is wildly off, I can't figure out why
Post by: Frank Kotler on March 29, 2014, 05:24:54 PM
Something like this? (not complete)
Code: [Select]
`section .data ; Welcome message wellmsg db "This program will compute the average of 10 2-digit numbers.",0xA wellmsglen equ \$-wellmsg askmsg db "Enter number #" askmsglen equ \$-askmsg section .bss numlist: resb 10 ; list of our numbers total: resd 1 ; to store the sum of the 10 numbers inputBufferSize equ 3 ; three characters (num1, num2 and enter key) inputBuffer resb inputBufferSize inputBufferEnd: outputBufferSize equ 10 outputBuffer resb outputBufferSize outputBufferEnd: section .text global _start    _start: ; print welcome message once mov eax, 4 mov ebx, 1 mov ecx, wellmsg mov edx, wellmsglen int 0x80 ; loop to run 10 times to read input and store number mov ecx, 0 prompt: ; store count push ecx ; prompt message mov eax, 4 mov ebx, 1 mov ecx, askmsg mov edx, askmsglen int 0x80;    pop eax ; get loop cunter back;    push eax ; put it back    mov eax, [esp]    inc eax ; we want to start with "1", not "0"    call print_num; need a space here, maybe a ":"    mov al, ':'    call print_char    mov al, ' '    call print_char ; get input number call get_num add [total], eax pop ecx inc ecx cmp ecx, 9 jne prompt    mov eax, [total]    call print_num ;exit mov eax, 1 mov ebx, 0 int 0x80 get_num: ; input into buffer mov eax, 3 mov ebx, 0 mov ecx, inputBuffer mov edx, inputBufferSize int 0x80 ; eax = length of string ; make esi the start of the string mov esi, inputBuffer ; make edi the end of the string mov edi, inputBuffer add edi, eax dec edi mov eax, 0get_num_loop: mov edx, 10 mul edx ; edx:eax = eax * operand mov edx, 0 mov dl, [esi] sub dl, 0x30 inc esi add eax, edx cmp esi, edi jne get_num_loop ret ; eax = inputed value print_num: ; point to the end of the buffer mov edi, outputBufferEnd print_num_loop: ; move one character left dec edi ; set up division mov edx, 0 mov ebx, 10 div ebx ; eax = edx:eax / ebx, remainder in edx ; put the remainder on the buffer add dl, 0x30 ; make it ASCII first mov [edi], dl ; if after the above division, eax != 0, continue to loop, otherwise exit the loop cmp eax, 0 jne print_num_loop ; set up registers and make system call mov eax, 4 mov ebx, 1 mov ecx, edi mov edx, outputBufferEnd sub edx, edi int 0x80 ret print_char:; prints the character in al    push edx    push ecx    push ebx    push eax ; must be pushed last - it's our "buffer"    mov ecx, esp ; our buffer    mov edx, 1 ; just one    mov ebx, 1    mov eax, 4    int 80h    pop eax    pop ebx    pop ecx    pop edx    ret`
Edit: well I see you've come up with essentially the same thing...

Best,
Frank

Title: Re: My sum is wildly off, I can't figure out why
Post by: ZimbuTheMonkey on March 29, 2014, 05:30:36 PM
Knowing that I did it in a similar fashion to yours is reassuring, to say the least.
Title: Re: My sum is wildly off, I can't figure out why
Post by: Frank Kotler on March 29, 2014, 05:38:40 PM
Don't feel too good about it - the reason I can spot mistakes (like your original one) is that I make a lot of them. :)

Best,
Frank

Title: Re: My sum is wildly off, I can't figure out why
Post by: ZimbuTheMonkey on March 29, 2014, 05:40:16 PM
I used your print_char function in my program.

Seems like a much smarter way than to define all the various chars I need individually.

Thanks again for the help, I appreciate it!