Author Topic: My sum is wildly off, I can't figure out why  (Read 3226 times)

Offline ZimbuTheMonkey

  • Jr. Member
  • *
  • Posts: 7
My sum is wildly off, I can't figure out why
« 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.
« Last Edit: March 29, 2014, 01:38:28 AM by ZimbuTheMonkey »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2379
  • Country: us
Re: My sum is wildly off, I can't figure out why
« Reply #1 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


Offline ZimbuTheMonkey

  • Jr. Member
  • *
  • Posts: 7
Re: My sum is wildly off, I can't figure out why
« Reply #2 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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2379
  • Country: us
Re: My sum is wildly off, I can't figure out why
« Reply #3 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, 0


get_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

      
            

Offline ZimbuTheMonkey

  • Jr. Member
  • *
  • Posts: 7
Re: My sum is wildly off, I can't figure out why
« Reply #4 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.
« Last Edit: March 29, 2014, 05:17:57 PM by ZimbuTheMonkey »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2379
  • Country: us
Re: My sum is wildly off, I can't figure out why
« Reply #5 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, 0


get_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




Offline ZimbuTheMonkey

  • Jr. Member
  • *
  • Posts: 7
Re: My sum is wildly off, I can't figure out why
« Reply #6 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.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2379
  • Country: us
Re: My sum is wildly off, I can't figure out why
« Reply #7 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


Offline ZimbuTheMonkey

  • Jr. Member
  • *
  • Posts: 7
Re: My sum is wildly off, I can't figure out why
« Reply #8 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!