#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2004
    Posts
    1
    Rep Power
    0

    convert c++ to assembly language


    hey guys,

    i really need help converting this c++ code to assembly. can anybody help me.

    Int GCD(int x, inty)
    {
    x=abs(x);
    y=abs(y);
    do{
    int n=x%y;
    x=y;
    y=n;
    }
    while y>0;
    return y;
    }


    i would really appreciate if anybody could help me convert to assembly language. thank you.
  2. #2
  3. No Profile Picture
    can't even complete a whole...
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2004
    Location
    Rotterdam, the Netherlands
    Posts
    428
    Rep Power
    11
    isn't it the easiest to compile it and disassemble it then? :p
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,156
    Rep Power
    2222
    Simply compile it with the option for an assembly listing.

    Eg:
    gcc GCD.c -s
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2003
    Posts
    705
    Rep Power
    12
    First off, the code presented won't compile until its fixed as in:

    Code:
    int GCD(int x, int y)
    {
     x=abs(x);
     y=abs(y);
    
     do{
         int n=x%y;
         x=y;
         y=n;
       }
        while (y>0);
    
     return y;
    }

    With that stipulated, Visual Studio 2k3 pops out this mess:

    Code:
    EXTRN	_abs:NEAR
    ; Function compile flags: /Odt /RTCsu /ZI
    ;	COMDAT ?GCD@@YAHHH@Z
    _TEXT	SEGMENT
    _n$10447 = -8						; size = 4
    _x$ = 8							; size = 4
    _y$ = 12						; size = 4
    
    
    ?GCD@@YAHHH@Z PROC NEAR					; GCD, COMDAT
    ; Line 23
    	push	ebp
    	mov	ebp, esp
    	sub	esp, 204				; 000000ccH
    	push	ebx
    	push	esi
    	push	edi
    	lea	edi, DWORD PTR [ebp-204]
    	mov	ecx, 51					; 00000033H
    	mov	eax, -858993460				; ccccccccH
    	rep stosd
    ; Line 24
    	mov	eax, DWORD PTR _x$[ebp]
    	push	eax
    	call	_abs
    	add	esp, 4
    	mov	DWORD PTR _x$[ebp], eax
    ; Line 25
    	mov	eax, DWORD PTR _y$[ebp]
    	push	eax
    	call	_abs
    	add	esp, 4
    	mov	DWORD PTR _y$[ebp], eax
    $L10444:
    ; Line 27
    	mov	eax, DWORD PTR _x$[ebp]
    	cdq
    	idiv	DWORD PTR _y$[ebp]
    	mov	DWORD PTR _n$10447[ebp], edx
    ; Line 28
    	mov	eax, DWORD PTR _y$[ebp]
    	mov	DWORD PTR _x$[ebp], eax
    ; Line 29
    	mov	eax, DWORD PTR _n$10447[ebp]
    	mov	DWORD PTR _y$[ebp], eax
    ; Line 31
    	cmp	DWORD PTR _y$[ebp], 0
    	jg	SHORT $L10444
    ; Line 32
    	mov	eax, DWORD PTR _y$[ebp]
    ; Line 33
    	pop	edi
    	pop	esi
    	pop	ebx
    	add	esp, 204				; 000000ccH
    	cmp	ebp, esp
    	call	__RTC_CheckEsp
    	mov	esp, ebp
    	pop	ebp
    	ret	0
    ?GCD@@YAHHH@Z ENDP					; GCD
    
    _TEXT	ENDS
    Which is a an unoptimized and perhaps ugly version of the assembler desired, but is a starting point.

    Now, a small amount of study is applied in comments below

    Code:
    EXTRN	_abs:NEAR
    ; Function compile flags: /Odt /RTCsu /ZI
    ;	COMDAT ?GCD@@YAHHH@Z
    _TEXT	SEGMENT
    _n$10447 = -8						; size = 4
    _x$ = 8							; size = 4
    _y$ = 12						; size = 4
    
    
    ?GCD@@YAHHH@Z PROC NEAR					; GCD, COMDAT
    ; Line 23
    
    
    
    
    ; frame setup stuff for C and C++, probably not important
    ; for a true assembler version
    
    	push	ebp
    	mov	ebp, esp
    	sub	esp, 204				; 000000ccH
    	push	ebx
    	push	esi
    	push	edi
    	lea	edi, DWORD PTR [ebp-204]
    	mov	ecx, 51					; 00000033H
    	mov	eax, -858993460				; ccccccccH
    	rep stosd
    
    ;the first of the abs calls - requires C runtime
    
    
    ; Line 24
    	mov	eax, DWORD PTR _x$[ebp]
    	push	eax
    	call	_abs
    	add	esp, 4
    	mov	DWORD PTR _x$[ebp], eax
    
    ; Line 25
    	mov	eax, DWORD PTR _y$[ebp]
    	push	eax
    	call	_abs
    	add	esp, 4
    	mov	DWORD PTR _y$[ebp], eax
    
    
    ; to avoid C runtime, you might change the above to something like
    ; note: I've not tested this, and my assembler is not practiced,
    ; so adjustment may be required
    
    ;  mov eax, DWORD PTR _x$[ebp]   ; get the value
    ;  cmp eax, 0                    ; compare against zero
    ;  jge positiveA                 ; if greater or equal, jump                       
    ;  neg eax                       ; if it didn't jump, it's negative, so negate it
    ; positiveA:
    ;  mov DWORD PTR _x$[ebp], eax ;  move the value (possibly negated into a positive value)
                                        ;  into destination
    
    ; above would be repeated for the second value
    
    
    
    
    
    ; as an example of optimization, the "abs" substitute above might be done
    ; second, instead of first, so that loading of eax could be avoided
    ; in the next instruction
    ; and, similarly, perform the ABS in, say, edx - or whatever, so the
    ; idiv could act upon the two registers (isn't that possible post Pentium)
    ; otherwise the following isn't all that "unclean"
    
    $L10444:
    ; Line 27
    	mov	eax, DWORD PTR _x$[ebp]
    	cdq
    	idiv	DWORD PTR _y$[ebp]
    	mov	DWORD PTR _n$10447[ebp], edx
    
    ; Line 28
    	mov	eax, DWORD PTR _y$[ebp]
    	mov	DWORD PTR _x$[ebp], eax
    
    ; Line 29
    	mov	eax, DWORD PTR _n$10447[ebp]
    	mov	DWORD PTR _y$[ebp], eax
    
    ; Line 31
    	cmp	DWORD PTR _y$[ebp], 0
    	jg	SHORT $L10444
    
    ; Line 32
    	mov	eax, DWORD PTR _y$[ebp]
    
    
    ; the following is stack cleanup junk that might be removed if the stack
    ; frame setup stuff is modified
    
    ; Line 33
    	pop	edi
    	pop	esi
    	pop	ebx
    	add	esp, 204				; 000000ccH
    	cmp	ebp, esp
    	call	__RTC_CheckEsp
    	mov	esp, ebp
    	pop	ebp
    	ret	0
    
    ?GCD@@YAHHH@Z ENDP					; GCD
    
    _TEXT	ENDS
    END

    My point in issueing this ugly mess is that when optimizing in assembler, you don't really want a C or C++ output, that wouldn't be any different than what C produced (in fact it would be exactly what C produced).

    If you use it as an assembler generator, you'll end up swapping things, cutting lots of stuff, and doing it in a manner that cuts out instructions to make it faster.
  8. #5
  9. No Profile Picture
    ......@.........
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2004
    Posts
    1,345
    Rep Power
    56
    A priori it looks like somebody told you that asm runs faster - and - you are trying to optimize code.

    First off - did you run a profiler to check where the bottleneck was? Don't just assume it's the GCD function.


    Secondly - your function always returns 0.

    Code:
    int GCD(int x, int y)
    {
          return 0;
    }
    would be the fastest implmentation of the function.

    And no, I'm not being a smart-***. Get your code working before you try to optimize :D
  10. #6
  11. No Profile Picture
    cien por ciento conejo.
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2004
    Posts
    411
    Rep Power
    11
    you could make that inline jimbo
  12. #7
  13. No Profile Picture
    ......@.........
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jun 2004
    Posts
    1,345
    Rep Power
    56
    Or a macro - even better.

IMN logo majestic logo threadwatch logo seochat tools logo