-1

I wrote a c code: convert integer to string and have a comma every 3 digits, and can anyone give me a hint how to convert it to assembly language??? I just want simply convert it into assembly language! Can't use other library call!

 #include <stdio.h>
char *my_itoa(int n, char *buf)
 {    
int i, j, k=0, l=0;
char tmp[32] = {0};

 i = n;
do {
    j = i%10;
    i = i/10;
    sprintf(tmp+k, "%d", j); 
    k++;
    l++;
    if (i!=0 && l%3 == 0) {
        sprintf(tmp+k, ",");
        k++;
        l = 0;
    }
}while(i);

for (k--,i=0; i<=k; i++) {
    buf[i] = tmp[k-i];
}

return buf;}
  • You can compile it with gcc for example and dump the generated assembly with -S flag. – VAndrei Oct 12 '14 at 17:17
  • Note that it's likely to be quite complicated, as sprintf() is probably a dynamic library function. – Chris Stratton Oct 12 '14 at 17:20
  • @ChrisStratton, the call to a library function will look like `call sprintf`. – artm Oct 12 '14 at 17:43
  • how is it exactly work?? just call sprintf?? – strugglingwithcode Oct 12 '14 at 17:46
  • it's a job of a **[dynamic library linker/loader](http://linux.die.net/man/8/ld-linux)** to figure out where to find sprintf. See link for details. – artm Oct 12 '14 at 17:53
  • @artm, no, it typically will not. Instead it will usually be a call into a procedure linkage table - following of course the positioning of the arguments. And there will be something somewhere in the generated code to get the dynamic linker involved. Compiled code is rarely trivial, but ends up with lots of non-obvious extras needed to make it work. – Chris Stratton Oct 12 '14 at 18:02
  • @ChrisStratton, I've ran the commands I suggested in my answer before commenting, I've seen what the compiler put in the assembly language output. Yes, the dynamic linking details are complicated, but they don't belong in the assembly output of a single function. – artm Oct 12 '14 at 18:20
  • I'm not saying assembly source isn't complicated, just that calling `sprintf` isn't the complicated part. – artm Oct 12 '14 at 18:22
  • You likely misinterpreted the output (if it's being labeled as "sprintf" that's only because your disassembler is smart enough to know about the PLT, and name the entry there as if it were the actual function) - but as the question doesn't specify a platform or toolchain (or even endorse that course of action) any experiment could be only anecdotal, and not definitive. As for what belongs in the assembly language answer to the question, presumably **everything required for it to function** - and for typical compiler-generated code, that is going to be all of these ugly details. – Chris Stratton Oct 12 '14 at 23:51
  • I'm not using a disassembler. I'm compiling C to assembly language. So all the details that a linker would add aren't in the output. – artm Oct 13 '14 at 06:40
  • If you dismiss anecdotal evidence, you can't assume `sprintf` comes form a dynamic library. The compiler doesn't assume that, it just inserts a call to undefined symbol and lets linker figure it out. But the OP didn't ask to decompile a linked executabe (and the source sample isn't enough to produce an executable), just to "convert it to assembly language". – artm Oct 13 '14 at 06:56

2 Answers2

2

If your complier is gcc, this answer suggests a nice way to produce a combined C/assembly language file that is easier to read than plain assembly. They use c++, but just replace c++ with gcc:

# create assembler code:
gcc -S -fverbose-asm -g original.c -o assembly.s
# create asm interlaced with source lines:
as -alhnd assembly.s > listing.lst
Community
  • 1
  • 1
artm
  • 3,559
  • 1
  • 26
  • 36
0

C compilers conforming to the SUSv2 (Single Unix Specification version 2 published in 1997) can do what you want much more simply by using a locale flag specifier. Here's example C code that works with gcc:

#include <stdio.h>
#include <locale.h>

int main() 
{
    int num = 12345678;
    setlocale(LC_NUMERIC, "en_US");
    printf("%'d\n", num);
    return 0;
}

This prints 12,345,678. Note, too, that this works correctly with negative numbers while your code does not. Because the code is simply a single library call, it's probably not worth implementing in assembly language, but if you still cared to, you could use this:

In the .rodata section include this string constant:

.fmt:
        .string  "%'d\n"

The code is extremely simple because all the hard work is done within printf:

        ;  number to be converted is in %esi
        movl    $.fmt, %edi
        movl    $0, %eax
        call    printf
Edward
  • 6,964
  • 2
  • 29
  • 55