Author Topic: plotting a pixel in dev cpp using inline asm  (Read 10730 times)

0 Members and 1 Guest are viewing this topic.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
i brought this over from my old board as i thought it might be helpfull this was jims answer to me asking about dev cpp inline asm.

quote jim:
Quote
Are you ready for this?..it's going to get seriously complicated! :-)

When you write programs with dev-c++ or gcc, gnuC, whatever it's called, the C or C++ is first translated to assembler, then 'as' or 'gas' (gnu assembler) turns that into an object file. The object files are linked together into the exe.
When you use inline assembler, you're basically turning off the C part of the compiler and that code gets spat straight out into the assembler.
So the first thing to do is make sure it's formatted correctly for the assembler. You need a tab at the start of the line and a new line at the end.
So you need
asm("\tmovl $5,eax\n");
\t is tab, \n is newline.

So, now to some real code. You could do a lot worse than go to  http://support.intel.com/design/PentiumD/documentation.htm and download and read the entire set of manuals from the Manuals section, especially Vol 1 which describes how the cpu works, and 2A and 2B which describe the entire (and huge) set of instructions you can work with.

The first thing you might want to do is to load the global variable 'screen_ptr' into a register. That's done with the 'mov' instruction.
asm("\tmov _screen_ptr,%esi\n");
That moves the value at 'screen_pointer' into the register esi. There are 8 registers, eax,ebx,ecx,edx,esi,edi,ebp,esp. You can use the first 6 for pretty much anything, the last two handle the stack.

When you pass values into a function, they appear on the stack. When you declare variables in a function they also appear on the stack. When you enter a function, esp points at the stack. Then a 'stack frame' is created to hold the local variables. This is done by subtracting the size of the variables off esp and placing it in ebp. Your x and y can be referenced off ebp. Now, I'm not quite sure how dev-c++ manages it's stack frame, but we can get the values of x and y by doing
asm("\tmov 8(%ebp),%eax\n");
asm("\tmov 12(%ebp),%ebx\n");

So, now you have x,y and the screen pointer, it should be possible to calculate the address of the pixel you want to write.
That is, screen_ptr + (x + y * 640)*4
We can do that by doing
asm("\timul $640,%ebx\n");
asm("\tadd %ebx,%eax\n");
asm("\tleal (%esi,%eax,4),%esi\n");

Now the address of the pixel is in esi. We can write the pixel (yay!)
asm("\tmovl $0xffff00ff,(%esi)\n");

There's still a bit of housekeeping to do. You may not corrupt esi or ebx in your inline asm, so you have to save them somewhere. The stack is a good place.
So before this code do
asm("\tpush %esi\n");
asm("\tpush %ebx\n");
then after
asm("\tpop %ebx\n");
asm("\tpush %esi\n");

There you go, a basic asm tutorial.

Here's the final routine cut&paste out of my app

Code: [Select]

void plot_pixel(int x, int y)
{
    asm("\tpush %ebx\n");
    asm("\tpush %esi\n");
    asm("\tmov 8(%ebp),%eax\n");
    asm("\tmov 12(%ebp),%ebx\n");
    asm("\tmov _screen_ptr,%esi\n");
    asm("\timul $640,%ebx\n");
    asm("\tadd %ebx,%eax\n");
    asm("\tleal (%esi,%eax,4),%esi\n");
    asm("\tmovl $0xffff00ff,(%esi)\n");
    asm("\tpop %esi\n");
    asm("\tpop %ebx\n");
}
Challenge Trophies Won:

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #1 on: October 02, 2006 »
That's what you'd call the AT and T syntax. Lillo once told me that it's cleaner than intel's but I still don't like it.

You could always use:

Code: [Select]
.intel_syntax noprefixDo inline asm in Devcpp.


Code: [Select]
asm(".intel_syntax noprefix
asm(    mov eax, 20
asm(    mov ebx, 20
asm(    add eax, ebx
asm(    mov x, eax\n");
Challenge Trophies Won:

Offline taj

  • Bytes hurt
  • DBF Aficionado
  • ******
  • Posts: 4810
  • Karma: 189
  • Scene there, done that.
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #2 on: October 02, 2006 »
In my experience, the \t isn't necessary. Here are some more GCC in-line tips from my experience.
 
One of the most expensive things to do in C is cast a float to an int...because of the rather restrictive IEEE spec on floating points.

So
Code: [Select]
int j=(int)f;

is a "no,no" for size coders. Unfortunately its very useful for synths to do calculations in float and then cast to shorts.

An alternative in in-line assembler for GCC is:

Code: [Select]
asm ("fistp %0" : "=m"(j) : "t"(f): "st");
This might save 50 bytes!

In brief it means, use the fistp intsruction on the floating point variable f, which should be at the top of the fp stack, and output to (=)the integer variable j.
The first part is the asm in a string, the second is always the output variables, the third the input variables and lastly, the "st" statement means to the compiler that the fp stack is used and corrupted during this assembler. This is called a clobber statement and is used to tell the compiler which registers are used by the assembler.

The key to remember is the C compiler and the assembler know nothing about each other. This means they can walk all over each others registers. You therefore have to tell the compiler which registers are used. I'm confused why I dont say here some register like eax too, but probably I get lucky and don't need to but it looks a little unsafe to me.

One more example:

Code: [Select]
s=sin(s);is
Code: [Select]
asm ("fsin" :"=t"(s) :"0"(s));
Using these two calls in a program saved me >70 bytes because I was no longer pulling in maths .dll, calling functions in it and so forth. Infact I was able to make a program 1k which simply wouldn't have fit otherwise.

(sin(s) isnt a double call in GCC under mingw *if* s is a float...the function is overloaded to be the same as fsin)

One more tip, with inline asm, sin and cos can be had in one instruction (fsincos) meaning spheres, circles etc are very efficient even in a C program. My personal belief is that a small library of such functions used in a C program is the best way to size code: it allows for maximum creativity and changing of ideas whilst avoids the big overheads that C introduces.

Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #3 on: October 02, 2006 »
cheers very much guys have some karma for that  :)

anything else anyone wants to add would be very much appreciated as im sure it would be most usefull to me and any one else learning.
Challenge Trophies Won:

Offline saida

  • C= 64
  • **
  • Posts: 57
  • Karma: 8
    • View Profile
    • saidas webpage
Re: plotting a pixel in dev cpp using inline asm
« Reply #4 on: October 02, 2006 »
huh?
Does the line ".intel_syntax noprefix" make it possible to code inline asm wihtout the crazy at&t syntax?
(or didnt I simply understand anything)

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #5 on: October 02, 2006 »
hello saida i think thats exactly what rel`s saying in which case itll benifit me because i was finding the at&t a real pain.
Challenge Trophies Won:

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #6 on: October 03, 2006 »
huh?
Does the line ".intel_syntax noprefix" make it possible to code inline asm wihtout the crazy at&t syntax?
(or didnt I simply understand anything)
Yep.

DevCPP uses GCC and GCC's Assembler is GAS. Incidentally, Freebasic's emitter uses GAS and outputs its asm code with ".intel_syntax noprefix" directive.
Challenge Trophies Won:

Offline saida

  • C= 64
  • **
  • Posts: 57
  • Karma: 8
    • View Profile
    • saidas webpage
Re: plotting a pixel in dev cpp using inline asm
« Reply #7 on: October 03, 2006 »
wow thats really awesome - ive been looking for a sollution to get arround the at&t syntax
Relsoft, im giveing you some karma, as soon as i figure out how ;)

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1668
  • Karma: 133
    • View Profile
Re: plotting a pixel in dev cpp using inline asm
« Reply #8 on: October 03, 2006 »
just hit the applaud button mate  ;)
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17426
  • Karma: 499
  • evil/good
    • View Profile
    • My Homepage
Re: plotting a pixel in dev cpp using inline asm
« Reply #9 on: October 03, 2006 »
He needs more posts before he can affect karma so I'll give Saida a post boost ;)

++ Posts
Shockwave ^ Codigos
Challenge Trophies Won:

Offline saida

  • C= 64
  • **
  • Posts: 57
  • Karma: 8
    • View Profile
    • saidas webpage
Re: plotting a pixel in dev cpp using inline asm
« Reply #10 on: October 04, 2006 »
thx ;)
Well, here is your carma relsoft
:cheers: