Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 657
  • Last Modified:

C++ Variables Sent to AT&T Inline Assembly

Hi, I'm very new here and I've searched for a while now, but I just don't have the knowledge base to answer this question for myself...  I believe I know what the problem is.  I'm trying to pass in variables that don't match the size of the registars I'm trying to pass them into.  I need to do this in AT&T because I'm using Dev-CPP 4 by bloodshed.

Now, this is a really easy 120 points because this is for a school project thats due in a very short amount of time.  Whoever submits working code will get the points, A pure explanation will not do as I don't know assembly very well, but feel free to include an explanation as well, that would be ideal.  I must stress that this code MUST work in Dev-CPP 4 because I can get the intel version to work in early (but not up to date) versions of Borland's compiler.  Sorry for being so picky guys but it is important.

Please Please help me, whoever submits the code will definitly be in the credits.  If you want you can go above and beyond and submit working code of a pixel plotting method that is faster than this one (that doesn't use DD or OpenGL ect) that also works in Dev-CPP 4 and I'll award the correct answer that way also.

Intel Syntax
_____________
#include <stdio.h>

#define VGA256 0x13
#define XMAX 320
#define YMAX 200

void pset(int x,int y,unsigned char color);
unsigned char get_mode(void);
void set_mode(unsigned char mode);

void main()
{
    unsigned char save,c;
    int x,y;

/* Initialze things */

    save = get_mode();      //Save current screen mode
    set_mode(VGA256);

/* Main routine */

    x=XMAX/2;
    y=YMAX/2;
    c=1;
    pset(x,y,c);

    getchar();

/* Reset stuff for end */

    set_mode(save);        //Restore screen mode
}

void pset(int x,int y,unsigned char color)
{
    _asm mov ah,0ch
    _asm mov al,color
    _asm mov cx,x
    _asm mov dx,y
    _asm int 10h
}

unsigned char get_mode(void)
{
    unsigned char mode;

    _asm mov ah,0fh
    _asm int 10h

    _asm mov mode,al
    return(mode);
}

void set_mode(unsigned char mode)
{
    _asm mov ah,00
    _asm mov al,mode
    _asm int 10h
}
_____________


My attempt at getting it into AT&T
_____________

#include <stdio.h>

#define VGA256 0x13
#define XMAX 320
#define YMAX 200

void pset(int x,int y,unsigned char color);
unsigned char get_mode(void);
void set_mode(unsigned char mode);

void main()
{
    unsigned char save,c;
    int x,y;

/* Initialze things */

    save = get_mode();      //Save current screen mode
    set_mode(VGA256);

/* Main routine */

    x=XMAX/2;
    y=YMAX/2;
    c=1;
    pset(x,y,c);

    getchar();

/* Reset stuff for end */

    set_mode(save);        //Restore screen mode
}

void pset(int x,int y,unsigned char color)
{
    __asm("mov $0x0c,%ah");
    __asm("mov color,%al");
    __asm("mov x,%cx");
    __asm("mov y,%dx");     //I believe a few of these lines can be simply
    __asm("int $0x10");     //replaced by loading the registers directly something like this
}                           //__asm("c", (x));  But I'll leave that to you before I muck it up.

unsigned char get_mode(void)
{
    unsigned char mode;

    __asm("mov $0x0f,%ah");
    __asm("int $0x10");

    __asm("mov mode,%al");
    return(mode);
}

void set_mode(unsigned char mode)
{
    __asm("mov $0x00,%ah");
    __asm("mov mode,%al");
    __asm("int $0x10");
}
0
Maxmike
Asked:
Maxmike
  • 4
  • 2
1 Solution
 
TascoDLXCommented:
Well, since this code works in DOS and not in Windows, I have no means of testing it.  And I'm not well versed in AT&T syntax, but here we go anyway...

1.  Variables must be prefixed with underscores when inlined.
2.  Only global variables can be referenced directly in Dev-C++ (as far as I know).

You could reference the variables via the stack pointer but, since I don't like muddling with AT&T asm, we'll throw your local variables into global variables.

I don't believe register size is an issue, but if it is, you can change the 'int's to 'short's at your leisure.


/**** New Code ****/

#include <stdio.h>

#define VGA256 0x13
#define XMAX 320
#define YMAX 200

void pset(int x,int y,unsigned char color);
unsigned char get_mode(void);
void set_mode(unsigned char mode);


/**** Global variables ****/

int g_x, g_y;
unsigned char g_color, g_mode;


void main()
{
   unsigned char save,c;
   int x,y;

/* Initialze things */

   save = get_mode();      //Save current screen mode
   set_mode(VGA256);

/* Main routine */

   x=XMAX/2;
   y=YMAX/2;
   c=1;
   pset(x,y,c);

   getchar();

/* Reset stuff for end */

   set_mode(save);        //Restore screen mode
}

void pset(int x,int y,unsigned char color)
{
   /**** Store passed variables in globals ****/

   g_x = x;
   g_y = y;
   g_color = color;

   /**** Reference global variables with underscores ****/

   __asm("mov $0x0c,%ah");
   __asm("mov _g_color,%al");
   __asm("mov _g_x,%cx");
   __asm("mov _g_y,%dx");
   __asm("int $0x10");
}

unsigned char get_mode(void)
{
   __asm("mov $0x0f,%ah");
   __asm("int $0x10");

   /**** More of the same ****/
   /**** Also corrected, was __asm("mov g_mode,%al"); ****/

   __asm("mov %al,_g_mode");

   return(g_mode);
}

void set_mode(unsigned char mode)
{
   /**** More of the same ****/

   g_mode = mode;

   __asm("mov $0x00,%ah");
   __asm("mov _g_mode,%al");
   __asm("int $0x10");
}

/**** End Code ****/


Of course this is pretty off-the-cuff.  Feel free to rewrite this to be more efficient.

Enjoy!
0
 
MaxmikeAuthor Commented:
I'll give that a try and get back to you, but there is indeed a way of directly passing in local variables...  This is the guide I used, if you look down at the extended AT&T code area you'll see...  I can actually get the passing to work, I can get ALL the code I posted to work, but I can't seem to convert the variables to the right types or sizes because I really don't understand enough about the assembly.  I'm sorry, I'd give you the correct answer, but I really hate Global variables where they are not needed.  However, if your coding does work and nobody comes up with something better in the next few days I'll grant you the points.

http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

0
 
MaxmikeAuthor Commented:
actually, it seems to work for the most part, and you did a good job in answering so I'll give you the points.  Before I do though...

The code compiles, links, but causes some sort of fault in windows.  *forehead smacking goodness on your part I'm sure* I really need the thing to work, and it isn't right now. :)  If someone could test it (I run XP despite myself and as I'm sure you've read Dev-CPP) that would be perfect and I'll award the points accordingly.

Thanks so far for your help and thank you in advance for any additional help I recieve.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
TascoDLXCommented:
I swear I can do it in Intel syntax, I just hate AT&T syntax.  Assuming 16-bit code, it's:

void pset(int x,int y,unsigned char color)
{
   _asm mov ah,0ch
   _asm mov al,BYTE PTR [sp+6]
   _asm mov cx,[sp+2]
   _asm mov dx,[sp+4]
   _asm int 10h
}

That's at least damn close.

As for your current situation, the program is not going to run in Windows because it uses direct system calls (latent ones for that matter).

It might work if you compile it as a DOS executable but Dev-C++ won't do that.  That old Borland compiler you mentioned compiles DOS executables.  You're living in Windows World now!

What is it you want to learn, DOS programming or Windows programming?

If it's Windows programming, go to http://msdn.microsoft.com, learn how to create a window and use GDI to draw a pixel.  Eventually, you'll probably want to learn DirectX programming as it's much faster.

If it's DOS programming, start searching.  My memory of DOS programming is quickly fading.  For 32-bit DOS programming, try DJGPP for a compiler and Allegro for drawing to the screen.  For 16-bit DOS programming, build yourself a time machine.

Oh and by the way, this is the faster way to draw a pixel:

void pset(int x, int y, unsigned char color)
{
   int coord = x + (y * 320);

   _asm mov al,color
   _asm mov [A000:coord],al
}

No guarantees though.
0
 
MaxmikeAuthor Commented:
ok, swank guys.  I basically wanted to do this without having to learn Windows programming... I don't really have enough time, but I suppose I could check it out.

I did download djgpp so I may give that code a look in there.

I guess I was hoping that there was some way to actually compile a dos program in dev-cpp I'll check the help files just incase.  I didn't think that direct functioncalls were impossible with windows, so I guess that's been alot of my problem.  I'll drop the answer in with you guys, but if there's any more advice in comment form I could recieve, that would be very much appreciated.
0
 
MaxmikeAuthor Commented:
hehe, I ended up going with SDL for Dev-C++
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now