Author Topic: Adding with Carry?  (Read 12268 times)

Offline BiancoAngelo

  • Jr. Member
  • *
  • Posts: 4
Adding with Carry?
« on: April 30, 2011, 03:15:45 AM »
Hello,

I'm having trouble understanding how to add with carry.

I made a program where the input(numbers) ends up in the AL register as a binary number (ASCII) code for the number pressed.  What I have to do is convert it to the right numerical value.  Well I did that.

The user has to input 4 digits and my program is supposed to add them.  However, since 4 digits mean the number is above 255, I'm getting the wrong result.  The overflow problem.  I'm supposed to use the Multiplication with carry or the Addition with carry.  But, it isn't working.

My output using the digits 0255

Please enter an integer that contains 4 digits or less:
0255
255


My output using the digits 0256

Please enter an integer that contains 4 digits or less:
0256
0



Code: [Select]
%include "/tools/lib/asm_io.inc"

segment .data

welcome_msg db 'Program Name: Lab 4', 0
prompt_msg db 'Please enter an integer that contains 4 digits or less: ', 0
typed_msg db 'You typed the number: ', 0
end_msg db 'Program has ended', 0

global _main

segment .text

_main:
enter 0, 0

mov eax, 0
mov eax, welcome_msg
call print_string ;Prints Program's Name
call print_nl

mov eax, prompt_msg
call print_string
call print_nl

mov ecx, 4 ;Sets counter to 3
mov dl, 0 ;dl = old number
mov bl, 0

call get_number
call print_nl
mov al, dl
call print_int


leave
ret

get_number:
call multiplication
call get_kb
sub al, 30h
call print_int
adc dl, al
mov bl, dl
dec ecx
jnz get_number
ret

multiplication:
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
adc dl, bl
ret


Thank you for your time.






Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Adding with Carry?
« Reply #1 on: April 30, 2011, 05:45:18 AM »
Well... 255 + 1 =0 is "correct" if you're going to stick with 8-bit registers... plus a carry, of course. That "carry" is what you want to capture with "adc", but there's no use adding with carry back into the same register. I think what you want to do is more like...

Code: [Select]
add dl, bl
adc dh, 0
;... many more times, perhaps

and then when you return from get_number, "mov ax, dx" instead of "mov al, dl" before the final "print_int". If I get what you're trying to do (your own read_int?) that may work.

If "_main" implies C, you may be in trouble for altering ebx and not restoring it. If your program crashes on exit, try adding "push ebx" right after "enter 0, 0" and "pop ebx" right before "leave"...

The "asm_io.inc" is Dr. Carter's stuff, I imagine? I suppose I could test it... maybe if an unexpected wave of ambition overcomes me... Anyway, try doing a plain "add" first to generate a carry (or not), and then "adc"ing it into an upper part of a register, and see if that helps...

Best,
Frank


Offline BiancoAngelo

  • Jr. Member
  • *
  • Posts: 4
Re: Adding with Carry?
« Reply #2 on: April 30, 2011, 10:36:42 AM »
Thank you very much sir.

I just got here from work and will test your advice in a few hrs (after some sleep).  The "_main" does not imply C though.  The "asm_io.inc" it's a file that the class is supposed to copy and use everytime we use "print_int, print_char, get_kb, etc".  I'm not sure if it's Dr. Carter's.

I will come back if I have anymore questions.

Hasta la vista!

Offline BiancoAngelo

  • Jr. Member
  • *
  • Posts: 4
Re: Adding with Carry?
« Reply #3 on: May 01, 2011, 12:17:20 AM »
Hello again,

I understand and I tried and it worked.

However, I'm having another issue.  Since, I have to keep adding to the "DX" register, how can I add more to it if the number is in the "BL" register?  I tried to make the "BL" register go over 255 and add with carry and therefore be able to use the "BX" register and then continue adding to the "DX" register.  But, I got results in the 10k or 60k.  Is my logic right?  This is supposed to be the simplest program in the class, but I simply can't understand this.  This is the only lab I have left, is this normal? or am I just too slow?

Code: [Select]
add bl, 170
adc bh, 0
sub bx, 170
add dx, bx

In this code is where I overflow "BL" on purpose by adding 170.  Obviously, there's a number there before the 170 so that there's an overflow and the carry flag gets set.  After that I substract the 170 so that I continue to have the old number.  Right, later on I add '"BX" and "DX".  Nonetheless,  the result like I said before is wrong.

In advance,

Thank you for your time!

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Adding with Carry?
« Reply #4 on: May 01, 2011, 06:03:58 AM »
What values were in bl, bh, and dx before you started this code? ASSuming some number in bl large enough to cause a carry (or even if not), zero in bh(?), and zero or some known value in dx, this looks like it should work. What result are you seeing?

Are you doing the "multiplication" this way because you have to or want to, or because you can't figure out "mul"?

Best,
Frank


Offline BiancoAngelo

  • Jr. Member
  • *
  • Posts: 4
Re: Adding with Carry?
« Reply #5 on: May 01, 2011, 07:41:12 PM »
In here I have the addition going on with bl, bh and bx.

Code: [Select]
%include "/tools/lib/asm_io.inc"

segment .data
msg1 db 'This is 255 + 1: '


global _main

segment .text

_main:
enter 0, 0

mov bl, 255
add bl, 1
adc bh, 0
mov eax, 0
mov ax, bx
call print_int
call print_nl

leave
ret

This is the output if I don't mov '0' to eax:

H:\test>make
/tools/NASM/nasm.exe    -f win32 test.asm
/tools/MinGW/bin/gcc.exe test.obj /tools/lib/COSC2425lib.a -o test.exe

H:\test>test
41216

H:\test>test
57600

H:\test>test
33024

H:\test>test
61696


This is the output if I mov '0' to eax:

H:\test>make
/tools/NASM/nasm.exe    -f win32 test.asm
/tools/MinGW/bin/gcc.exe test.obj /tools/lib/COSC2425lib.a -o test.exe

H:\test>test
41216

H:\test>test
57600

H:\test>test
33024

H:\test>test
61696


I guess I have to do everything in the eax register and its daughters for the add with carry to work.

This is only with the al, ah register:

Code: [Select]
%include "/tools/lib/asm_io.inc"

segment .data
msg1 db 'This is 255 + 1: '


global _main

segment .text

_main:
enter 0, 0

mov al, 255
add al, 1
adc ah, 0
call print_int
call print_nl

leave
ret

Output:
H:\test>make
/tools/NASM/nasm.exe    -f win32 test.asm
/tools/MinGW/bin/gcc.exe test.obj /tools/lib/COSC2425lib.a -o test.exe

H:\test>test
256
« Last Edit: May 01, 2011, 07:54:20 PM by BiancoAngelo »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Adding with Carry?
« Reply #6 on: May 02, 2011, 04:42:01 AM »
No, you shouldn't need to use eax, ax, ah, al - works fine with bx - but bh needs to be zero when you start!

Quote
/tools/MinGW/bin/gcc.exe test.obj /tools/lib/COSC2425lib.a -o test.exe

... thought you told me this didn't involve C!

I haven't got that library, but I managed to fudge it up to build with Dr.Carter's tools (apparently what you've got is pretty similar). It definitely works. I just did "xor ebx, ebx" but any way to zero bh should do.

Since this does involve C, you really ought to preserve ebx! (but it seems to work without it...)

Best,
Frank