0

Hello I'm making a base 10 calculator in assembler that can take number with max length of 5 dig... so there is two numbers after the input was taken one of the five dig number is stored in ax and bl for example

AX - 23 45
BX - 00 01

So the value of the input is 12345 And the other is for example is 23243 and it's stored on CX and DX with the same idea of the first number (that stored in AX and BX...) Now, I have made the addition code, but I can't figure out how making the Subtraction code with all the neg problem...

So what I thought to do is to, for example, take bh (that I'm not using because the number can't be longer than 6 digs...) and if the number is negative Ill put 1 and if its positive I'll put 0 so this problem is solved, Now the problem is that I dont know how to make the code work like with all the sub part and the carry and every thing ...(in the addition i used commands like adc,daa...)

last example: value is: 12345 and its positive

AX - 23 45  
BX - 00 01 
(if Bh is 0 the number is positive if 1 its negative...)

Now the value is : 23243 and its positive CX - 32 43 DX - 00 02

Calculation 12345-23243(= -10898)

lets say the answer goes to CX AND DX so it will look like that:

CX - 08 98
DX - 01 01

answer: (-10898)

Can someone please help me/give me an example code that I'll know how to do it ?

Sorry if I'm little bit Confused...

Thx. EDIT: here is the addition code that you ask for:

proc Add_two_numbers;2 values useing stack...
    pop [150]
    pop dx
    pop cx
    pop bx
    pop ax
    add al,cl
    daa 
    mov cl,al
    mov al,ah
    adc al,ch
    daa
    mov ch,al
    mov al,bl
    adc al,dl
    daa
    mov dl,al
    push cx
    push dx
    push [150]
    ret
endp Add_two_numbers  

2nd edit: I figure out how making it Negative so I just need algorithms that sub 2 number it does not need to work with numbers like 1000-2000 please make it work only on positive values like 2000-1000

BananaBuisness
  • 339
  • 2
  • 18
  • It would help to tag the specific assembly you are using... x86? – Segmented Mar 09 '15 at 18:28
  • 2
    Also can you show a relevant snippet of the code you are using? Personally I would recommend you convert to binary and work with that, and then convert back... – Segmented Mar 09 '15 at 18:31
  • Sorry emu8086 I don't have the code of the subtraction but I have the addition is it ok? – BananaBuisness Mar 09 '15 at 18:46
  • If it helps illustrate what you are intending to do with the subtraction, sure. – Segmented Mar 09 '15 at 18:47
  • I think it may give a better perspective so yah... One sec... – BananaBuisness Mar 09 '15 at 18:48
  • Storing each base-10 digit in a separate register makes things unnecessarily complicated. I see here no reason for doing that. I'd recommend storing each signed or unsigned number in 1 or 2 16-bit registers as usual (eg. `dx:ax` for one value and `cx:bx` for the other). If the inputs are strings, use `atoi` from C library to convert each string to integer or implement your own. Then do the subtraction with `sub` and `sbb`. Then do the printing with `printf` or implement your own. – nrz Mar 09 '15 at 19:02
  • Can't use libraries :P – BananaBuisness Mar 09 '15 at 19:03
  • Only pure assembly... – BananaBuisness Mar 09 '15 at 19:03
  • So I imagine you would do something similar to what you did with ADC+DAA... SUB+DAS should work no? I don't think BCD's can hold negative values on their own, you will have to detect the overflow from the flag and go from there... HTH – Segmented Mar 09 '15 at 19:24
  • But will itbe in a shape of negative* number like "ffff1" ? Or it will be neg but the number will stay "positive" – BananaBuisness Mar 09 '15 at 19:26
  • Not sure, I haven't worked with BCD arithmetic, but if you do get a value like that you can convert it back using 2's complement. A simpler solution might be to detect ahead of time if you are subtracting a larger value from a smaller one, and flip the values and add the sign after. – Segmented Mar 09 '15 at 19:28
  • 1
    I think you are missing the point. Decimal numbers are not for processors. Although they provide minimal conversion facilities decimal is for humans. Get the interface right: convert decimal to binary at the man/machine interface, before computation, and convert it back at the point of output. – Weather Vane Mar 09 '15 at 20:35
  • @WeatherVane I don't know how to convert the decimal to binary at the interface can you give me a hint? – BananaBuisness Mar 10 '15 at 15:01
  • As @Segmented suggests, you can use `sbb` and `das`. But BCD operations don't know anything about "negative" numbers. If you subtract a larger number from a smaller, you'll get a "10's complement" number. For example, if you have 6 BCD digit operations, and you compute, `2000-2123` you'll get `999877`, but you really want `-123`, which is the 10's complement of `999877` with a `-` in front (10's complement is determined by taking the complement of each digit relative to `9`, then adding `1`, so `000122 + 1` or `123`). – lurker Mar 11 '15 at 23:42

1 Answers1

1

Answering your comment, this is one way you can convert from decimal and back using C as an example. I leave you to code it in asm!

#include <conio.h>

#define MAX  100000000

// input a signed decimal number
int inp_num(void) {
    int number=0, neg=0, key;
    while (number < MAX) {
        key = _getche();
        if (key == '-') {
            if (number==0)
                neg = 1;        // else ignore
        }
        else if (key >= '0' && key <= '9')
            number = number * 10 + key - '0';
        else
            break;
    }
    if (neg)
        number = -number;
    _putch('\n');
    return number;
}

// output a signed number as decimal
void out_num(int number) {
    int digit, suppress0, d;
    suppress0 = 1;              // zero-suppression on
    if (number < 0) {
        _putch('-');
        number =-number;
    }
    for (d=MAX; d>0; d/=10) {
        digit = number / d;
        if (digit)              // if non-0
            suppress0 = 0;      // cancel zero-suppression
        if (!suppress0)
            _putch('0' + digit);
        number -= digit * d;
    }    
}

int main(void) { 
    int number;
    number = inp_num();
    out_num(number);
    return 0;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56