Anyone know what's wrong?
12 replies to this topic
#1
Posted 12 December 2010 - 04:38 PM
I tried making a function that converts a double-word into a string. For some numbers, this function works, however, for other numbers I don't exactly know what it does.
Anyone know what's wrong?
Anyone know what's wrong?
|
|
|
#2
Posted 14 December 2010 - 11:05 AM
What numbers doesn't it work for? Do you notice a pattern? I suggest you write the function in standard C first and then convert that to assembly language. I see that you tried that, but it's in a somewhat weird syntax and your variable names aren't that helpful.
sudo rm -rf /
#3
Posted 14 December 2010 - 06:45 PM
I think a C++ (I don't quite know how different C and C++ are) version, with more helpful variable names, would look something like:
I didn't really get this code to work on my C++ compiler, but that's kind of the idea.
The variable 'e' is supposed to be used to tell where, in the integer, the function is at. It is supposed to divide the integer by 10 to the 'e' power, add 48 to it (ASCII 48 is the character "0"), and store it as a character at the character, pointed to by the 'theString' variable. Then it is supposed to decrement 'e' and recurse, passing the same 'theInteger' to itself, with the pointer to the output string character + 1 (the next character to be written to, in the string) at the 'theString' parameter. When 'e' finally equals -1, the function is supposed to set 'e' back to 9 (for future d2string() calls) and return.
I tried using the asm function (the one I posted earlier) with 100, 150, 149, 300, 200 as inputs and 100 got converted to "100", 150 got converted to "154", 149 got converted to "143", 300 got converted to "304", and 200 got converted to "204."
I don't really notice anything wrong in the code, so I don't know what's wrong.
int e= 9;
int d2string(int theInteger, char *theString){
char a;
if (e == -1){
*theString= 0;
e= 9;
} else {
a= (theInteger / exp10(e));
while (a >= 10) e -= 10;
while (a < 0) e += 10;
*theString= (a + 48);
e--;
d2string(theInteger, (theString + 1));
}
return 0;
}
int exp10(int theExponent){
int i= 1;
int a;
for (a= 0; a < theExponent; a++){
i *= 10;
}
return i;
}
I didn't really get this code to work on my C++ compiler, but that's kind of the idea.
The variable 'e' is supposed to be used to tell where, in the integer, the function is at. It is supposed to divide the integer by 10 to the 'e' power, add 48 to it (ASCII 48 is the character "0"), and store it as a character at the character, pointed to by the 'theString' variable. Then it is supposed to decrement 'e' and recurse, passing the same 'theInteger' to itself, with the pointer to the output string character + 1 (the next character to be written to, in the string) at the 'theString' parameter. When 'e' finally equals -1, the function is supposed to set 'e' back to 9 (for future d2string() calls) and return.
I tried using the asm function (the one I posted earlier) with 100, 150, 149, 300, 200 as inputs and 100 got converted to "100", 150 got converted to "154", 149 got converted to "143", 300 got converted to "304", and 200 got converted to "204."
I don't really notice anything wrong in the code, so I don't know what's wrong.
Edited by dargueta, 14 December 2010 - 06:46 PM.
Added code tags
#4
Posted 14 December 2010 - 06:49 PM
If your C/C++ code doesn't work, how do you expect the assembly code to work? I tested this code and it works:
#include <stdint.h>
void dword2str(uint32_t num, char *buf)
{
const char *digits = "0123456789";
uint32_t i, divisor;
if( num == 0 )
{
buf[0] = '0';
buf[1] = '\0';
return;
}
divisor = 1000000000; /* 10 decimal digits for DWORD, so init to 10^9 */
while( num / divisor == 0 )
divisor /= 10;
for( i = 0; divisor > 0; ++i )
{
buf[i] = digits[num / divisor];
num = num % divisor;
divisor /= 10;
}
buf[i] = '\0';
}
Try converting that into assembly language and see if you still have problems.
sudo rm -rf /
#5
Posted 14 December 2010 - 07:07 PM
What does "num % divisor" (the "%", in particular) mean?
#6
Posted 14 December 2010 - 07:08 PM
% is the modulus, the remainder of num / divisor. For example:
10 / 3 = 3
10 % 3 = 1
10 / 3 = 3
10 % 3 = 1
sudo rm -rf /
#7
Posted 14 December 2010 - 11:10 PM
I made another function. I think this one works.
Thanks for the help.
;; void d2a ( int theInteger, char * theString ){
;; d2aProc ( theInteger, theString );
;; reverse_string ( theString );
;; }
;; void d2aProc ( int theInteger, char *theString ){
;; char a;
;; int i= theInteger;
;; if (theInteger == 0){
;; *(theString + 0)= 48;
;; *(theString + 1)= 0;
;; return;
;; }
;; while (i >= 10) i -= 10;
;; a= i;
;; *theString= a + 48;
;; d2aProc ( ( theInteger / 10 ), ( theString + 1 ) );
;; }
d2a proc
enter 0, 0
pusha
theInteger equ ebp + 8
theString equ ebp + 12
push dword ptr [theString]
push dword ptr [theInteger]
call d2aProc
push dword ptr [theString]
call reverse_string
mov eax, dword ptr [theString]
mov ebx, eax
mov ah, 48
call skip_to_non_char
mov eax, dword ptr [theString]
call StringCopy
popa
leave
ret 8
d2a endp
d2aProc proc
enter 8, 0
theInteger equ ebp + 8
theString equ ebp + 12
a equ ebp - 4
i equ ebp - 8
mov eax, dword ptr [theInteger]
mov dword ptr [i], eax
;mov eax, dword ptr [theInteger] ;; eax is already equal to [theInteger]
cmp eax, 0
jnz d2aProcOver1
mov eax, dword ptr [theString]
mov ebx, eax
mov byte ptr [ebx+0], 48
mov byte ptr [ebx+1], 0
leave
ret 8
d2aProcOver1:
lp1:
cmp dword ptr [i], 10
jl lp1s
sub dword ptr [i], 10
jmp lp1
lp1s:
mov eax, dword ptr [i]
mov byte ptr [a], al
mov eax, dword ptr [theString]
mov ebx, eax
mov al, byte ptr [a]
add al, 48
mov byte ptr [ebx], al
;mov eax, dword ptr [theString]
mov eax, ebx ;; since ebx == [theString] (at this point)
inc eax
push eax
push dword ptr 10
push dword ptr [theInteger]
call divide4
push eax
call d2aProc
leave
ret 8
d2aProc endp
Thanks for the help.
#8
Posted 31 December 2010 - 04:36 PM
I think this function (the function that you gave me in C/C++) works too. I tried converting it to assembly and here's how it is:
And here's what "div4.asm" has:
.386
.model flat, stdcall
option casemap:none
option prologue:none
option epilogue:none
include \string.inc
dword2str proto
.data
.data?
.code
dword2str proc
enter 12, 0
num equ ebp + 8
buf equ ebp + 12
digits equ ebp - 12
divisor equ ebp - 8
i equ ebp - 4
mov dword ptr [digits], string("0123456789")
mov eax, dword ptr [num]
cmp eax, 0
jnz dword2str_over1
mov eax, dword ptr [buf]
mov ebx, eax
mov byte ptr [ebx+0], 48
mov byte ptr [ebx+1], 0
leave
ret 8
dword2str_over1:
mov dword ptr [divisor], 1000000000
lp1:
push dword ptr [divisor]
push dword ptr [num]
call divide4
cmp eax, 0
jnz lp1s
push dword ptr 10
push dword ptr [divisor]
call divide4
mov dword ptr [divisor], eax
jmp lp1
lp1s:
mov dword ptr [i], 0
lp2:
mov eax, dword ptr [divisor]
cmp eax, 0
jng lp2s
push dword ptr [divisor]
push dword ptr [num]
call divide4
add eax, dword ptr [digits]
mov edx, eax
mov eax, dword ptr [buf]
add eax, dword ptr [i]
mov ebx, eax
mov al, [edx]
mov [ebx], al
;; num= num % divisor
push dword ptr [divisor]
push dword ptr [num]
call divide4
mov dword ptr [num], ecx
push dword ptr 10
push dword ptr [divisor]
call divide4
mov dword ptr [divisor], eax
inc dword ptr [i]
jmp lp2
lp2s:
mov eax, dword ptr [buf]
add eax, dword ptr [i]
mov ebx, eax
mov byte ptr [ebx], 0
leave
ret 8
dword2str endp
include div4.asm
end
And here's what "div4.asm" has:
divide4 proc
enter 4, 0
a equ ebp + 8
b equ ebp + 12
i01 equ ebp - 4
push ecx
push edx
;; int i= 0;
;; while ((b * i) <= a){
;; i++;
;; }
mov dword ptr [i01], 0
lp003:
mov eax, dword ptr [b]
mov ecx, dword ptr [i01]
imul eax, ecx
cmp eax, dword ptr [a]
jg lp003s
inc dword ptr [i01]
jmp lp003
lp003s:
dec dword ptr [i01]
mov eax, dword ptr [b]
imul eax, dword ptr [i01]
neg eax
add eax, dword ptr [a]
pop edx
pop ecx
mov ecx, eax
mov eax, dword ptr [i01]
;; eax= a / b; ecx= a % b;
leave
ret 8
divide4 endp
#9
Posted 01 January 2011 - 04:12 AM
That's a little over-complicating things. Here's what I came up with; I don't have time to comment it too well right now, but if you have questions just ask. I map some variables to registers:
ECX: divisor
EBX: 10
EDI: buf
EAX: num (most of the time)
ECX: divisor
EBX: 10
EDI: buf
EAX: num (most of the time)
global dword2str section .text dword2str: push ebp mov ebp, esp push ebx push edi mov eax, [ebp + 8] mov edi, [ebp + 12] or eax, eax jnz .nonzero mov BYTE [edi], '0' mov BYTE [edi + 1], 0 jmp .done .nonzero: mov ecx, 1000000000 mov ebx, 10 .div_loop: xor edx, edx div ecx or eax, eax jnz .buf_loop xor edx, edx mov eax, ecx div ebx mov ecx, eax mov eax, [ebp + 8] jmp .div_loop .buf_loop: xor edx, edx mov eax, [ebp + 8] div ecx mov [ebp + 8], edx ; num = num % divisor mov dl, [digits + eax] ; buf[i] = digits[num / divisor] mov [edi], dl ; divisor /= 10 xor edx, edx mov eax, ecx div ebx mov ecx, eax ; ++i inc edi or ecx, ecx jnz .buf_loop .add_null: mov BYTE [edi], 0 .done: pop edi pop ebx pop ebp ret section .data digits: db "0123456789", 0x00
sudo rm -rf /
#10
Posted 01 January 2011 - 05:36 PM
I tried this:
And it seems to work, also.
global dword2str, _dword2str section .text _dword2str: jmp dword2str ;; ..... dword2str: %define divisor ecx %define buf edi %define num eax push ebp mov ebp, esp push ebx push edi mov num, [ebp + 8] mov buf, [ebp + 12] or num, num jnz .nonzero mov BYTE [buf], 48 mov BYTE [buf + 1], 0 jmp .done .nonzero: mov divisor, 1000000000 mov ebx, 10 .div_loop: xor edx, edx div divisor or num, num jnz .buf_loop xor edx, edx mov eax, divisor div ebx mov divisor, eax mov num, [ebp + 8] jmp .div_loop .buf_loop: xor edx, edx mov num, [ebp + 8] div divisor mov [ebp + 8], edx ; num = num % divisor mov dl, [digits + eax] ; buf[i] = digits[num / divisor] mov [buf], dl ; divisor /= 10 xor edx, edx mov eax, divisor div ebx mov divisor, eax ; ++i inc buf or divisor, divisor jnz .buf_loop .add_null: mov BYTE [buf], 0 .done: pop edi pop ebx pop ebp ret section .data digits: db "0123456789", 0x00
And it seems to work, also.
#11
Posted 01 January 2011 - 06:59 PM
#12
Posted 01 January 2011 - 07:16 PM
Just changed things like 'mov eax, [ebp+8]' to 'mov num, [ebp+8]', with the '%define num eax' at the beginning of the function.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account



Back to top









