Please tell me your LOGIC
Please tell me your LOGIC
Hi to all ASM guru here.
I wish to seek some help from your people.
I wish to know is there any other LOGIC ways to put (ascii number) in memory data into register.
example,
let says,
intA db 33,34,35
intB db 36,37,38
so basically, the intA is (345h) in ASCII and intB is (678h) in ASCII
so, the question is, how if we want to add this two numbers to become 9BDh?
I assume we must be able to make the register AX,BX,CX or DX to contain
these two number.
eg.
AX = 345
BX = 678
so how can we put these numbers into register (in numeric form) so that we can add them later?
I wish to seek some help from your people.
I wish to know is there any other LOGIC ways to put (ascii number) in memory data into register.
example,
let says,
intA db 33,34,35
intB db 36,37,38
so basically, the intA is (345h) in ASCII and intB is (678h) in ASCII
so, the question is, how if we want to add this two numbers to become 9BDh?
I assume we must be able to make the register AX,BX,CX or DX to contain
these two number.
eg.
AX = 345
BX = 678
so how can we put these numbers into register (in numeric form) so that we can add them later?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Please tell me your LOGIC
well, you cannot do it in one shot. But basically, you will loop the 'string of numbers', substracting '0' (or 0x30) to each of them to get the value of each digit, and accumulate x = x * 10 + digit in some register.
When you're done with one value, you do the same with the other one, and then add ...
There's an intermediary representation called 'Binary Coded Decimal' which the x86 CPU supports and that is able to tell you that 0x00030405 + 0x00060708 is 0x01000203
btw, except if you have specific reasons to do things at once, i suggest you split the problem in int_to_str(str_to_int("345") + str_to_int("678") ...
When you're done with one value, you do the same with the other one, and then add ...
There's an intermediary representation called 'Binary Coded Decimal' which the x86 CPU supports and that is able to tell you that 0x00030405 + 0x00060708 is 0x01000203
btw, except if you have specific reasons to do things at once, i suggest you split the problem in int_to_str(str_to_int("345") + str_to_int("678") ...
Re:Please tell me your LOGIC
Actually, the formula would be [tt]x += base[sup]order[/sup] * c[/tt], where 'order' is the place in the number from right to left. Even this isn't complete; since Sulaiman specifically said he needed it to work with hex, it would also need to convert the letter-numerals to their correct numeric value. A full algorithm would be:Pype.Clicker wrote: well, you cannot do it in one shot. But basically, you will loop the 'string of numbers', substracting '0' (or 0x30) to each of them to get the value of each digit, and accumulate x = x * 10 + digit in some register.
[tt]s == the string holding the number
c == the current character
x == the current loop index
accumulator == the accumulated final value
cvalue == the numeric value of the current character to be converted
base == the base of the number to be converted
order == the order of the numeral in question (that is, the unit place, the tens place, the hundreds place, and so on)
size == the size of the number
order = 0;
accumulator = 0;
find the size of the number held in string s;
for x from (size - 1) down to 0
c = s[sup]x[/sup] forced to upper case;
if c is a number then
cvalue = ASCII value of c - ASCII '0';
else, since c must then be a valid letter-numeral,
cvalue = ASCII value of c - ASCII 'A';
accumulator += base[sup]order[/sup] * cvalue;
increment order;
end for
return accumulator;
[/tt]
The good news is, so long as you have the suitable handling for letter-numerals, the algorithm is pretty much general for any base. Here's a version of it in C (including a test program):
Code: Select all
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define INT_OFFSET 0x30 /* ASCII offset for integers */
#define CHAR_OFFSET 0x41 /* ASCII offset for capital letters */
#define max(x, y) (((x) >= (y)) ? (x) : (y))
int string2int (char s[], int base)
{
char c;
int i;
int cvalue;
int order = 0; /* the order of the numeral in the number */
int acc = 0;
for (i = (size_of_number(s, base) - 1); i >= 0; i--, order++)
{
c = toupper(s[i]);
if (isdigit(c))
cvalue = (int) c - INT_OFFSET;
else
/* since you know it is before the end of the integer,
assume it is a valid letter-numeral */
cvalue = (int) c - CHAR_OFFSET + 10;
acc += pow(base, order) * cvalue;
}
return acc;
}
int size_of_number(char s[], int base)
{
int i;
char c;
int base_offset = max(0, base - 10);
c = toupper(s[0]);
for (i = 1;
(isdigit(c)) || (isalpha(c) && (((int) c - CHAR_OFFSET) < base_offset));
i++)
c = toupper(s[i]);
i--;
return i;
}
#define NUMCOUNT 6
#define NUMSIZE 3
int main()
{
char numbers[NUMCOUNT][NUMSIZE] = {"5", "10", "24", "30", "1A", "bf"};
int count;
int base;
puts("Original Strings:");
for(count = 0; count < NUMCOUNT; count++)
printf(" %s", numbers[count]);
puts("\n");
puts("Number sizes in base 16:");
for(count = 0; count < NUMCOUNT; count++)
printf(" %d", size_of_number(numbers[count], 16));
puts("\n");
for (base = 8; base <= 16; base++)
{
printf("base %d:", base);
for(count = 0; count < NUMCOUNT; count++)
printf(" %d", string2int(numbers[count], base));
puts("\n");
}
}
True, but that only works for base 10 numerals.There's an intermediary representation called 'Binary Coded Decimal' which the x86 CPU supports and that is able to tell you that 0x00030405 + 0x00060708 is 0x01000203
Re:Please tell me your LOGIC
(logic is a noun)
there is no point in adding ascii characters
(subtracting is another story)
from the moment you press a key (on the keyboard)
the internal ascii representation is a byte (8 bits)
a number's representation doesnt change accordingly to its base,
which means that functions like printf are responsible for the look
why would anyone convert a string to a number ??
a 1000 character string is nothing,
but a 1000 digit number sucks!
usually 'a' is enough for a preprocessor to extract its ascii value,
not by calculation, but some sort of indexing database
in another database 'a' might have a different value
so to keep things portable just use the god damn thing
db is a macro
quite surprising for a so called assembly
this is supposed to be low level staff
db "hello world" is totally unacceptable
what's wrong with
inta db 'a'
intb db 0x17h
mov ax, inta or sth
really ?!
you dont mess with decimals
all transcripts are to binary, then you do whatever ..
ever heard of
sscanf(s,"%d",&n);
sprintf(s,"%d",n);
atoi() etc
what is your problem anyway ???
reading asm tutorials .. who could imagine!
there is no point in adding ascii characters
(subtracting is another story)
from the moment you press a key (on the keyboard)
the internal ascii representation is a byte (8 bits)
a number's representation doesnt change accordingly to its base,
which means that functions like printf are responsible for the look
why would anyone convert a string to a number ??
a 1000 character string is nothing,
but a 1000 digit number sucks!
usually 'a' is enough for a preprocessor to extract its ascii value,
not by calculation, but some sort of indexing database
in another database 'a' might have a different value
so to keep things portable just use the god damn thing
db is a macro
quite surprising for a so called assembly
this is supposed to be low level staff
db "hello world" is totally unacceptable
what's wrong with
inta db 'a'
intb db 0x17h
mov ax, inta or sth
really ?!
you dont mess with decimals
all transcripts are to binary, then you do whatever ..
ever heard of
sscanf(s,"%d",&n);
sprintf(s,"%d",n);
atoi() etc
what is your problem anyway ???
reading asm tutorials .. who could imagine!
Re:Please tell me your LOGIC
you may be right, swth, but be careful of the ghosts you invoke with your arrogant manner to write. Your writing leads me to the impression of a big moron thinking he 's the worlds one and only navel.
In short words, you sound like a git.
In short words, you sound like a git.
Re:Please tell me your LOGIC
Plus it's confusing:
please sort them out
or you may find
a visit from the delete-o-tron
swth, your posts are beginning to do more harm than good.db "hello world" is totally unacceptable
please sort them out
or you may find
a visit from the delete-o-tron
Re:Please tell me your LOGIC
If you code the bits yourself, the divide & multiply also work for different bases (second byte of the opcode is base).Schol-R-LEA wrote:True, but that only works for base 10 numerals.There's an intermediary representation called 'Binary Coded Decimal' which the x86 CPU supports and that is able to tell you that 0x00030405 + 0x00060708 is 0x01000203
Re:Please tell me your LOGIC
since we want to mul 16 or 10 or 8 for different base.
any idea, we just SHL or SHR the number and + or - the value to get the result.
example,
intA db 3,4,5 ;assume decimal (minus 30h already)
so, we want to make this three hundred and forty-five in our register AX.
is there any way, we just SHL or SHR the first number (3) and plus / minus the result so that we can obtain 300 // three hundred in our register?
and SHL or SHR the second number (4) and + / - the result so that we can get 40.
any formula?
because I don't think the big software company out there will use times 10 to obtain the result, coz if the user have a number eg. 10000000000000000000000000012 in memory,
how are they going to translate it into register?
It means they got to multiple 10 for around 28 times.
any idea, we just SHL or SHR the number and + or - the value to get the result.
example,
intA db 3,4,5 ;assume decimal (minus 30h already)
so, we want to make this three hundred and forty-five in our register AX.
is there any way, we just SHL or SHR the first number (3) and plus / minus the result so that we can obtain 300 // three hundred in our register?
and SHL or SHR the second number (4) and + / - the result so that we can get 40.
any formula?
because I don't think the big software company out there will use times 10 to obtain the result, coz if the user have a number eg. 10000000000000000000000000012 in memory,
how are they going to translate it into register?
It means they got to multiple 10 for around 28 times.
Re:Please tell me your LOGIC
They're going to convert it to either 4294967295 (YES! finally know 2^32 out of the back of my head!) being the largest number a 32-bit int can represent, or to 18446744073709551615 being the largest number a 64-bit int can represent (nope, used calc.exe for that one...).sulaiman wrote: because I don't think the big software company out there will use times 10 to obtain the result, coz if the user have a number eg. 10000000000000000000000000012 in memory,
how are they going to translate it into register?
If it's put into a floating point register, it's going to be hard to convert, but I'd suggest looking into the FILD instruction on x86es, that does just that. Page 3-251 on the intel manual volume 2A.
anyway, the only reason you'd use these functions is when the user enters a number (how fast did users type again? 50 MBit of inbound traffic?) or when files containing plaintext numbers are loaded. I can nearly guarantee you, that barely ever happens.
Re:Please tell me your LOGIC
..or they are going to represent it with multiple 32-bit or 64-bit numbers, just like we humans use multiple base-10 decimals to represent a big number. Isn't especially hard after all..Candy wrote: They're going to convert it to either 4294967295 (YES! finally know 2^32 out of the back of my head!) being the largest number a 32-bit int can represent, or to 18446744073709551615 being the largest number a 64-bit int can represent (nope, used calc.exe for that one...).
Re:Please tell me your LOGIC
>> because I don't think the big software company out there will use times 10 to obtain the result
Not necessarily. You might be suprised (I wouldn't) to find that many commercial applications are riddled with inefficiencies like that. It all depends on the quality of the coding, the development language(s) used, the underlying implementation of any third-party code that may be in use, etc, etc, etc.
Anyway, to multiply a number by 10 using shifts is easy - just use the algorithm:
x = (x << 3) + (x << 1);
To multiply by 16, just shift the number left 4 times.
To convert a string of hexadecimal characters to an unsigned integer in C might look something like:
- Sebastian
Not necessarily. You might be suprised (I wouldn't) to find that many commercial applications are riddled with inefficiencies like that. It all depends on the quality of the coding, the development language(s) used, the underlying implementation of any third-party code that may be in use, etc, etc, etc.
Anyway, to multiply a number by 10 using shifts is easy - just use the algorithm:
x = (x << 3) + (x << 1);
To multiply by 16, just shift the number left 4 times.
To convert a string of hexadecimal characters to an unsigned integer in C might look something like:
Code: Select all
unsigned hextoint(const char * s)
{
unsigned val, result = 0;
while(*s == ' ')
{
++s;
}
while(*s != 0 && *s != '\n')
{
val = *s++;
if(val >= 'A' && val <= 'F') // convert to lowercase
{
val += 0x20;
}
if(val >= 'a' && val <= 'f')
{
val -= 'a';
val += 0x0a;
}
else if(val >= '0' && val <= '9')
{
val -= '0';
}
else
{
return 0;
}
result = (result << 4) + val;
}
return result;
}
- Sebastian
Re:Please tell me your LOGIC
and i am thinking about a better to do things like this.
i will use your algorithm in my next post...
but i am thinking something else here,
how about byte to byte operation.
eg.
consider (something like this) not real code, just to describe
the idea in my mind.
n1= 1234567890 in memory (each integer is one byte size)
n2= 9876543210 in memory (each integer also one byte size)
nTotal = times 11 db 0;
// GOL = get offset length i == 10
i = (GOL n1 > GOL n2) ? GOL n1 : GOL n2;
p = i++ // index for storing the total one.., should be one byte more than the longest length "n" byte.
start:
mov ax,[n1 + i]
if( [n1 + i] || [n2 + i ] == 0 ) {
mov [nTotal + p], n1 or n2 who is not zero
jmp start
}
add ax, [n1+i], [n2+i], [nTotal+p]
pushf
mov [nTotal+p], ax
p--
i--
popf
jc got_plus_one
jmp start
got_plus_one:
mov [nTotal+p], 1
jmp start
num2reg.asm
======
Code: Select all
; yup, this is the algorithm i search for.
x = (x << 3) + (x << 1);
but i am thinking something else here,
how about byte to byte operation.
eg.
consider (something like this) not real code, just to describe
the idea in my mind.
n1= 1234567890 in memory (each integer is one byte size)
n2= 9876543210 in memory (each integer also one byte size)
nTotal = times 11 db 0;
// GOL = get offset length i == 10
i = (GOL n1 > GOL n2) ? GOL n1 : GOL n2;
p = i++ // index for storing the total one.., should be one byte more than the longest length "n" byte.
start:
mov ax,[n1 + i]
if( [n1 + i] || [n2 + i ] == 0 ) {
mov [nTotal + p], n1 or n2 who is not zero
jmp start
}
add ax, [n1+i], [n2+i], [nTotal+p]
pushf
mov [nTotal+p], ax
p--
i--
popf
jc got_plus_one
jmp start
got_plus_one:
mov [nTotal+p], 1
jmp start
num2reg.asm
======
Code: Select all
org 100h
jmp start
num1 db 3,4,5,20 ; to ease the problem, i use decimal number directly.
num2 db 6,7,8,20 ; 20 equal to termination
numTotal dw 0 ; numTotal must contain 1023 // 3FF in the end
byte_num_add:
xor ax,ax
xor bx,bx
byte_num_add_start:
cmp byte [si],20
je byte_num_add_return
mov al,[si]
push ax
mov ax,10
mul bx
pop bx
add bx,ax
inc si
jmp byte_num_add_start
byte_num_add_return:
ret
start:
mov si,num1 ; offset of num1
call byte_num_add
mov [numTotal],bx
mov si,num2 ; offset of num2
call byte_num_add
mov ax,[numTotal]
add bx,ax
mov [numTotal],bx
jmp finish
finish:
mov ah,4ch
int 21h
Re:Please tell me your LOGIC
As I see you want to use assembly, try:sulaiman wrote:i will use your algorithm in my next post...Code: Select all
; yup, this is the algorithm i search for. x = (x << 3) + (x << 1);
but i am thinking something else here,
how about byte to byte operation.
Code: Select all
mov eax, x
next_number:
shl eax, 1
lea eax, [eax + eax*4 - 48]
add eax, [number] ; the ascii number
cmp [number], end_character
jne next_number