| | |
How do I convert c code to asm
Please support our Assembly advertiser: Programming Forums - DaniWeb Sister Site
![]() |
•
•
Join Date: Jul 2009
Posts: 1
Reputation:
Solved Threads: 0
hi everyone
I hope you can help me with converting some c code into assembly code, i have tried much now, and i still don't get it.
i'm new to programming ASM
this c code gets two number from the user to draw an ellipse
my asm code
I hope you can help me with converting some c code into assembly code, i have tried much now, and i still don't get it.
i'm new to programming ASM
this c code gets two number from the user to draw an ellipse
Assembly Syntax (Toggle Plain Text)
#include<stdio.h> #include<graphics.h> #include<math.h> #include<dos.h> void main() { long d1,d2; long rx,ry,rxsq,rysq,tworxsq,tworysq,dx,dy; int gd=DETECT,gm,x,y; clrscr(); printf("enter x radius of the ellipse(20)"); scanf("%ld",&rx); printf("enter y radius of the ellipse(40)"); scanf("%ld",&ry); initgraph(&gd,&gm,""); rxsq=rx*rx; rysq=ry*ry; tworxsq=2*rxsq; tworysq=2*rysq; x=0; y=ry; d1=rysq-rxsq*ry+(0.25*rxsq); dx=tworysq*x; dy=tworxsq*y; do{ putpixel(200+x,200+y,15); putpixel(200-x,200-y,15); putpixel(200+x,200-y,15); putpixel(200-x,200+y,15); if(d1<0) { x=x+1; y=y; dx=dx+tworysq; d1=d1+dx+rysq; } else { x=x+1; y=y-1; dx=dx+tworysq; dy=dy-tworxsq; d1=d1+dx-dy+rysq; } delay(200); } while(dx<dy); // in dige yani chi ? d2=rysq*(x+0.5)*(x+0.5)+rxsq*(y-1)*(y-1)-rxsq*rysq; do{ putpixel(200+x,200+y,15); putpixel(200-x,200-y,15); putpixel(200+x,200-y,15); putpixel(200-x,200+y,15); if(d2>0){ x=x; y=y-1; dy=dy-tworxsq; d2=d2-dy+rxsq; } else { x=x+1; y=y-1; dy=dy-tworxsq; dx=dx+tworysq; d2=d2+dx-dy+rxsq; } } while(y>0); getch(); }
Assembly Syntax (Toggle Plain Text)
putpix macro x,y mov cx,x mov dx,y mov ah,0ch mov al,9 int 10h endm init macro mov al,13h mov ah,0 int 10h endm .model small .stack 128 .data d1 dw 0 d2 dw 0 rx dw 0 ry dw 0 rxsq dw 0 rysq dw 0 tworxsq dw 0 tworysq dw 0 x dw 0 y dw 0 dxx dw 0 dyy dw 0 km1 dw 0 km2 dw 0 km3 dw 0 two dw 2 four dw 4 .code main proc far mov ax,@data mov ds,ax init mov rx,30 mov ry,10 mov ax,rx mul ax mov rxsq,ax mov ax,ry mul ax mov rysq,ax mov ax,rxsq mul two mov tworxsq,ax mov ax,rysq mul two mov tworysq,ax mov x,0 mov bx,ry mov y,bx ;----- ;d1=rysq-rxsq*ry+(0.25*rxsq) ;4d1=4rysq-4rxsq*ry+(rxsq); ; mov ax,rysq mul four mov cx,ax ; mov ax,rxsq mul ry mul four mov bx,ax ; sub cx,bx add cx,rxsq ; mov ax,cx div four mov d1,ax ;----- mov ax,rxsq mul two mov dxx,ax mov ax,rysq mul two mov dyy,ax ;***loop1 lw1:cmp dxx,ax jge endw1 ;200+x mov bx,x add bx,200 ;200+y mov cx,y add cx,200 putpix bx,cx ;200-x mov bx,x sub bx,200 neg bx ;200-y mov cx,y sub cx,200 neg cx putpix bx,cx ;200+x mov bx,x add bx,200 ;200-y mov cx,y sub cx,200 neg cx putpix bx,cx ;200-x mov bx,x sub bx,200 neg bx ;200+y mov cx,y add cx,200 putpix bx,cx cmp d1,0 jge else1 inc x mov bx,tworysq add dxx,bx mov bx,rysq add d1,bx jmp ifexit1 else1: inc x dec y mov bx,tworysq add dxx,bx mov bx,tworxsq sub dyy,bx ;d1=d1+dx-dy+rysq; mov bx,dxx sub bx,dyy add bx,rysq add d1,bx ifexit1: mov cx,09999h l12: loop l12 jmp lw1 endw1: ;d2=rysq*(x+0.5)*(x+0.5)+rxsq*(y-1)*(y-1)-rxsq*rysq; ;4d2=rysq*(2x+1)*(2x+1)+4rxsq*(y-1)*(y-1)-4rxsq*rysq; ;4d2=km1+km2+km3 ;km1 mov ax,x mul two add ax,1 mul ax mul rysq mov km1,ax ;km2 mov ax,y dec ax mul ax mul rxsq mul four mov km2,ax ;km3 mov ax,rxsq mul ax mul four mov km3,ax mov ax,km1 add ax,km2 add ax,km3 div four mov d2,ax ;***loop2 lw2: cmp y,0 jle endw2 ;200+x mov bx,x add bx,200 ;200+y mov cx,y add cx,200 putpix bx,cx ;200-x mov bx,x sub bx,200 neg bx ;200-y mov cx,y sub cx,200 neg cx putpix bx,cx ;200+x mov bx,x add bx,200 ;200-y mov cx,y sub cx,200 neg cx putpix bx,cx ;200-x mov bx,x sub bx,200 neg bx ;200+y mov cx,y add cx,200 putpix bx,cx cmp d2,0 jle else2 dec y mov bx,tworxsq sub dyy,bx ;d2=d2-dy+rxsq; mov bx,rxsq add bx,dyy sub d2,bx jmp ifexit2 else2: inc x dec y mov bx,tworxsq sub y,bx add dx,tworysq ;d2=d2+dx-dy+rxsq; mov bx,dxx add bx,rxsq sub bx,dyy sub d2,dx ifexit2: jmp lw2 endw2: getch:mov ah,0 int 16h mov ah,4ch int 21h main endp end main
Looks like you're trying to do a deviation of the Bresenham DDA algorithm. Is this a class assignment or a personal or work project?
This is a big function. One method is to dump the assembly code generated by the compiler to get some ideas.
It also looks like you're not trying to write this for speed! You're stalling the processor almost all the time!
Interesting thing about a DDA algorithm, it uses a binary base in conjunction with increment/decrement. Rework your C code to be closer in appearance to the assembly!
How volatile is the putpixel() function? If X,Y are preserved then no need to move from memory to registers for each pixel. Just modify the displacement!
Years ago I wrote a graphics driver for drawing lines, circles, etc. With the Bresenham DDA algorithm but using self modifying code for fastest speed! If you're using an older pre Pentium computer you should be able to do the same. But one step at a time.
Okay, reformating your code while typing this have noticed a few things in the c code! Shouldn't y=y not be there? And It looks like your error correction is d1 ? (e) might be more familiar here!
Stop mixing floating-point with your integer code. Not
*0.25 instead >>2
You're dealing with integers...
d1 = rysq - rxsq*ry + (0.25*rxsq);
should be more like
d1 = rysq - rxsq*ry + (rxsq >>2);
DO NOT...
mul 4
Do a shift
much much faster!!!
Your operations such as...
...is WRONG!
- ( x - 200)
See the problem!
Instead use something like the following!
Store your 200 in a register, interlace the +/- x/y math then process.
This is a big function. One method is to dump the assembly code generated by the compiler to get some ideas.
It also looks like you're not trying to write this for speed! You're stalling the processor almost all the time!
Interesting thing about a DDA algorithm, it uses a binary base in conjunction with increment/decrement. Rework your C code to be closer in appearance to the assembly!
How volatile is the putpixel() function? If X,Y are preserved then no need to move from memory to registers for each pixel. Just modify the displacement!
Years ago I wrote a graphics driver for drawing lines, circles, etc. With the Bresenham DDA algorithm but using self modifying code for fastest speed! If you're using an older pre Pentium computer you should be able to do the same. But one step at a time.
Okay, reformating your code while typing this have noticed a few things in the c code! Shouldn't y=y not be there? And It looks like your error correction is d1 ? (e) might be more familiar here!
Stop mixing floating-point with your integer code. Not
*0.25 instead >>2
You're dealing with integers...
d1 = rysq - rxsq*ry + (0.25*rxsq);
should be more like
d1 = rysq - rxsq*ry + (rxsq >>2);
DO NOT...
mul 4
Do a shift
Assembly Syntax (Toggle Plain Text)
shl ax,2
Assembly Syntax (Toggle Plain Text)
div 4 asr ax,2
Your operations such as...
Assembly Syntax (Toggle Plain Text)
mov bx,x sub bx,200 neg bx
- ( x - 200)
See the problem!
Instead use something like the following!
Store your 200 in a register, interlace the +/- x/y math then process.
Assembly Syntax (Toggle Plain Text)
mov si,200 ; Center X axis mov di,200 ; Center Y axis mov bx,si ; +x +y mov cx,di add bx,x add cx,y putpix bx,cx mov bx,si ; -x -y mov cx,di sub bx,x sub cx,y putpix bx,cx mov bx,si ; +x -y mov cx,di add bx,x sub cx,y putpix bx,cx mov bx,si ; -x +y mov cx,di sub bx,x add cx,y putpix bx,cx
Last edited by wildgoose; Jul 19th, 2009 at 6:28 am.
•
•
Join Date: Jul 2009
Posts: 15
Reputation:
Solved Threads: 0
thank you Mr wildgoose for your reply
i fix some errors
i fix putmix macro
and i use shift operation instead of mul
and fixed some other things like x=x & y=y but still doesn't work
i fix some errors
i fix putmix macro
and i use shift operation instead of mul
and fixed some other things like x=x & y=y but still doesn't work
Assembly Syntax (Toggle Plain Text)
putpix macro x,y mov ax,0A000h mov es,ax ;{es = $A000} mov ax,y shl ax,6 mov bx,ax ;{bx = y * 64} shl ax,1 shl ax,1 ;{ax = y * 256} add bx,ax ;{bx = y * 320} add bx,x ;{bx = y * 320 + x} mov al,9 ;{load color} mov es:[bx],al ;{set point} endm init macro mov al,13h mov ah,0 int 10h endm .model small .stack 128 .data d1 dw 0 d2 dw 0 rx dw 0 ry dw 0 rxsq dw 0 rysq dw 0 tworxsq dw 0 tworysq dw 0 x dw 0 y dw 0 dxx dw 0 dyy dw 0 km1 dw 0 km2 dw 0 km3 dw 0 two dw 2 four dw 4 .code main proc far mov ax,@data mov ds,ax init mov rx,30 mov ry,10 mov ax,rx mul ax mov rxsq,ax mov ax,ry mul ax mov rysq,ax ; tworxsq=2*rxsq; ; tworysq=2*rysq; mov ax,rxsq shl ax,1 mov tworxsq,ax mov ax,rysq shl ax,1 mov tworysq,ax ;x=0; ;y=ry; mov x,0 mov bx,ry mov y,bx ;----- ;d1=rysq-rxsq*ry+(0.25*rxsq) ;d1=rysq-rxsq*ry+(rxsq>>4); ; mov bx,rxsq shr bx,2 add bx,rysq mov ax,rxsq mul ry sub ax,bx neg ax mov d1,ax ;----- ;dx=tworysq*x; mov ax,tworysq mul x mov dxx,ax ;dy=tworxsq*y; mov ax,tworxsq mul y mov dyy,ax ;***loop1 lw1:cmp dxx,ax jge endw1 mov si,200 ; Center X axis mov di,200 ; Center Y axis mov bx,si ; +x +y mov cx,di add bx,x add cx,y putpix bx,cx mov bx,si ; -x -y mov cx,di sub bx,x sub cx,y putpix bx,cx mov bx,si ; +x -y mov cx,di add bx,x sub cx,y putpix bx,cx mov bx,si ; -x +y mov cx,di sub bx,x add cx,y putpix bx,cx cmp d1,0 jge else1 ;y=y; ??? mov y,y inc x mov bx,tworysq add dxx,bx mov bx,rysq add d1,bx jmp ifexit1 else1: inc x dec y mov bx,tworysq add dxx,bx mov bx,tworxsq sub dyy,bx ;d1=d1+dx-dy+rysq; mov bx,dxx sub bx,dyy add bx,rysq add d1,bx ifexit1: mov cx,09999h l12: loop l12 jmp lw1 endw1: ;d2=rysq*(x+0.5)*(x+0.5)+rxsq*(y-1)*(y-1)-rxsq*rysq; ;d2=rysq*(x+0.5)*(x+0.5)+rxsq*(y-1)*(y-1)-rxsq*rysq; ;4d2=rysq*(2x+1)*(2x+1)+4rxsq*(y-1)*(y-1)-4rxsq*rysq; ;4d2=km1+km2+km3 ;km1 mov ax,x mul two add ax,1 mul ax mul rysq mov km1,ax ;km2 mov ax,y dec ax mul ax mul rxsq mul four mov km2,ax ;km3 mov ax,rxsq mul ax mul four mov km3,ax mov ax,km1 add ax,km2 add ax,km3 div four mov d2,ax ;***loop2 lw2: cmp y,0 jle endw2 mov si,200 ; Center X axis mov di,200 ; Center Y axis mov bx,si ; +x +y mov cx,di add bx,x add cx,y putpix bx,cx mov bx,si ; -x -y mov cx,di sub bx,x sub cx,y putpix bx,cx mov bx,si ; +x -y mov cx,di add bx,x sub cx,y putpix bx,cx mov bx,si ; -x +y mov cx,di sub bx,x add cx,y putpix bx,cx cmp d2,0 jle else2 dec y mov bx,tworxsq sub dyy,bx ;d2=d2-dy+rxsq; mov bx,dyy sub bx,rxsq ; neg bx add d2,bx jmp ifexit2 else2: inc x dec y mov bx,tworxsq sub y,bx add dx,tworysq ;d2=d2+dx-dy+rxsq; mov bx,dxx add bx,rxsq sub bx,dyy add d2,dx ifexit2: jmp lw2 endw2: getch:mov ah,0 int 16h mov ah,4ch int 21h main endp end main
Last edited by kiuhnmgrtdcv; Jul 19th, 2009 at 9:55 am.
Of course it doesn't work. You were suppose to analyze what I did, review your code, and single-step, etc. and make appropriate changes! One typically doesn't learn by being handed the answer. They typically need to be nudged into the correct direction so they can hopefully find the answer themselves!
Did you analyze what putpix does? If you had you would have seen that it uses bx for the offset calculation for the 256 color pixel write. You were using the BIOS call before, but now you are writing directly to memory.
What two registers are you passing in? AND what registers are pixel write using?
What processor are you using? This may be 16-bit 8086 code but are you running on a modern day Pentium type or an old 8086 through 80486? If a newer computer then using the old shifting for the multiplication is a mistake! On the older processors multiple shifts waas MUCH faster then a multiply. But on the newer processors it is quite the reverse of that!
I don't like heavy macros like you're using because of this kind of mistake. YOU DO NOT NEED TO KEEP RESETTING ES to the Video segment!!! You aren't using it anywhere else, so set it at your code initialization, and not in the write for each pixel!
Second, You aren't calling a function to plot each pixel so why are you using real X and real Y for each pixel write?
How many bytes in a stride? # of pixels for one pixel row? According to your own code 320. You use an anchor point each time.
so once you calculate your starting position (anchor point of elipse).
(+x) gets right edge -(x*2) gets left edge
(+y) gets bottom edge -(y*2) gets top edge.
Once you get this working post again, there are multitudes of optimizations you can do!
Did you analyze what putpix does? If you had you would have seen that it uses bx for the offset calculation for the 256 color pixel write. You were using the BIOS call before, but now you are writing directly to memory.
What two registers are you passing in? AND what registers are pixel write using?
What processor are you using? This may be 16-bit 8086 code but are you running on a modern day Pentium type or an old 8086 through 80486? If a newer computer then using the old shifting for the multiplication is a mistake! On the older processors multiple shifts waas MUCH faster then a multiply. But on the newer processors it is quite the reverse of that!
I don't like heavy macros like you're using because of this kind of mistake. YOU DO NOT NEED TO KEEP RESETTING ES to the Video segment!!! You aren't using it anywhere else, so set it at your code initialization, and not in the write for each pixel!
Second, You aren't calling a function to plot each pixel so why are you using real X and real Y for each pixel write?
How many bytes in a stride? # of pixels for one pixel row? According to your own code 320. You use an anchor point each time.
so once you calculate your starting position (anchor point of elipse).
(+x) gets right edge -(x*2) gets left edge
(+y) gets bottom edge -(y*2) gets top edge.
Once you get this working post again, there are multitudes of optimizations you can do!
Last edited by wildgoose; Jul 19th, 2009 at 2:10 pm.
•
•
Join Date: Jul 2009
Posts: 15
Reputation:
Solved Threads: 0
•
•
•
•
My question is, why are you still using fossil-ware?
I mean, how many Gigs of (processor speed, memory, hard disk) do you have?
A whole football field to play in, and you're still scribbling on the back of an old envelope.
i have no plan to develope an os or write the driver of the graphic card
i know with assembly we can crack applications through disAsm..
personaly i use c# and java to earn money
thank you Mr wildgoose for commenting
Last edited by kiuhnmgrtdcv; Jul 19th, 2009 at 3:43 pm.
•
•
Join Date: Jul 2009
Posts: 15
Reputation:
Solved Threads: 0
finally i find a source that draws an ellipse!
but i have a problem when i try to tasm it please help
http://img2.pict.com/5c/e0/0d/1348515/0/untitled.gif
http://img2.pict.com/5c/e0/0d/1348515/0/untitled.gif
but i have a problem when i try to tasm it please help
http://img2.pict.com/5c/e0/0d/1348515/0/untitled.gif
Assembly Syntax (Toggle Plain Text)
.MODEL small .DATA ; Draws an ellipse using Floating point arithmetic X_centre EQU [si] ;Centre of the ellipse Y_centre EQU [si+2] ; A EQU word ptr [si+4] ;Ellipse 1/2 width B EQU word ptr [si+6] ;Ellipse 1/2 height colour EQU byte ptr [si+8] ;Colour attribute plotadot EQU [si+14] ;Address of the pixel plotting routine X_offset dw ? ;X distance from ellipse centre Y_offset dw ? ;Y " " " temp dw ? ;Scratch variable ;------------------------------------------------------------------------------- .CODE PUBLIC ellipse ;-----------------------------------------------; ; Plot the ellipse defined by the equation ; ; ; ; X**2/A**2 + Y**2/B**2 = 1 ; ; ; ; Where, 2A is the ellipse width and B is the ; ; ellipse height. A is > B ; ; ; ; Entry: si = address of parameter block ; ; es = Address of video memory ; ;-----------------------------------------------; ellipse proc uses ax bx cx dx mov al,colour ; 1st plot the pixels at the extremities of the ellipse mov cx,X_centre mov dx,Y_centre add dx,B ;Add on the ellipse 1/2 height call plotadot ;Top pixel located above centre location mov dx,Y_centre sub dx,B ;Subtract the ellipse 1/2 height call plotadot ;Bottom pixel located below the centre add cx,A ;Add the ellipse 1/2 width mov dx,Y_centre call plotadot ;Rightmost pixel mov cx,X_centre sub cx,A ;Subtract the ellipse 1/2 width call plotadot ;Leftmost pixel ; Calculate the Y coordinates corresponding to all positions X from centre mov cx,A ;Set loop index to ellipse 1/2 width dec cx ;Don't need to do the extreme positions eloop: push cx ;Save the loop index mov temp,cx ;Get the X position fild temp fimul temp ;st=X**2 fild A ;st=A,st(1)=X**2 fimul A ;st=A**2,st(1)=X**2 fdiv ;st=X**2/A**2 fld1 ;st=1, st(1)=X**2/A**2 fsubr ;st = 1 - X**2/A**2 fsqrt ;st = SQRT(1-X**2/A**2) fimul B ;st = B*SQRT(1-X**2/A**2) fistp y_offset mov dx,Y_offset mov X_offset,cx ;Take a copy of the X offset mov cx,X_centre add cx,X_offset mov dx,Y_centre add dx,Y_offset call plotadot ;X_centre+X_offset, Y_centre+Y_offset mov dx,Y_centre sub dx,Y_offset call plotadot ;X_centre+X_offset, Y_centre-Y_offset mov cx,X_centre sub cx,X_offset call plotadot ;X_centre-X_offset, Y_centre-Y_offset mov dx,Y_centre add dx,Y_offset call plotadot ;X_centre_X_offset, Y_centre+Y_offset skip: pop cx ;Restore the loop index loop eloop ret ellipse endp end
http://img2.pict.com/5c/e0/0d/1348515/0/untitled.gif
Last edited by kiuhnmgrtdcv; Jul 27th, 2009 at 7:30 am.
USES is typically a MASM thing and its about register preservation. I don't use TASM but you can remove the uses line, and merely push bx yourself. AX, CX, DX are typically scratch but BX is preserved thus make sure it gets pushed, and then popped.
The version of TASM you are using is DOS based and thus 16-bit (REAL MODE), same as the code. I'm assuming you've added other code to put the computer into graphics mode and calls this function. Also that you've created a plotadot function? You can easily rework this function to fit your application!
Interesting. I don't see bx inuse, Most likely used by plotadot.
Too much heavy math for a DDA but kind of looks like a DDA. Will have to pick it apart to understand the math better!
The version of TASM you are using is DOS based and thus 16-bit (REAL MODE), same as the code. I'm assuming you've added other code to put the computer into graphics mode and calls this function. Also that you've created a plotadot function? You can easily rework this function to fit your application!
Assembly Syntax (Toggle Plain Text)
void ellipse( short cx, short cy, // center of ellipse short width, short height, char color, // 2 bytes ? short pad[2], // 4 bytes funcptr *plotadot 2 bytes );
Interesting. I don't see bx inuse, Most likely used by plotadot.
Too much heavy math for a DDA but kind of looks like a DDA. Will have to pick it apart to understand the math better!
Last edited by wildgoose; Jul 27th, 2009 at 11:15 am.
This algorithm only deals with a fixed orientation of an ellipse but it uses the width for the stepping factor. Which means that if you set the width to half the height or thinner, you will see holes between pixels. Once you get this working you should modify the algorithm to use whichever is the longest, width or height as the stepping factor. It will replot some pixels but should be a consistent drawn line of pixels, and not a series of dotted pixels. And I'm guessing the reason the corners were painted separately is that the algorithm was not inclusive of its limits. [0,width) 0<=x<width not 0<=X<=width, thus they wouldn't have been plotted. But will have to analyze the math to know for sure!
So once you get this working, you should improve upon the algoithm to make your version your own. Since you did 'find' this version, you really should have posted credit to the original author, otherwise it really is plagiarism!
So once you get this working, you should improve upon the algoithm to make your version your own. Since you did 'find' this version, you really should have posted credit to the original author, otherwise it really is plagiarism!
Last edited by wildgoose; Jul 27th, 2009 at 11:46 am.
![]() |
Similar Threads
- How to convert C code to C++ (C++)
- convert this code in c (C)
- Convert C code to Assembly code (Assembly)
- plz Help , ...source code for this app. (C++)
- can any body help me to convert this code from C++ to C (C)
- Convert python code to C++ (C++)
- need help convert MASM to ASM 8086 (Assembly)
- C++ to ASM (C++)
Other Threads in the Assembly Forum
- Previous Thread: I need help in these programs
- Next Thread: a86 converting numbers
Views: 1104 | Replies: 16
| Thread Tools | Search this Thread |
Tag cloud for Assembly
3d 68hc11 6811 80386 :( adress array asm assembler assembly boot bootloader buffer compression cursor debug directory division docs dos draw emulator endtask error exceptions file int10h integer intel interrupt interrupts language loop newbie nohau osdevelopment print program range read remainder shape string text theory tsr x86






