?
Solved

C++ Variables Sent to AT&T Inline Assembly

Posted on 2003-03-16
6
Medium Priority
?
655 Views
Last Modified: 2007-12-19
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
Comment
Question by:Maxmike
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
6 Comments
 
LVL 3

Accepted Solution

by:
TascoDLX earned 480 total points
ID: 8149937
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
 

Author Comment

by:Maxmike
ID: 8150104
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
 

Author Comment

by:Maxmike
ID: 8150180
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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 3

Expert Comment

by:TascoDLX
ID: 8150888
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
 

Author Comment

by:Maxmike
ID: 8151902
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
 

Author Comment

by:Maxmike
ID: 8179242
hehe, I ended up going with SDL for Dev-C++
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recently, in one of the tech-blogs I usually read, I saw a post about the best-selling video games through history. The first place in the list is for the classic, extremely addictive Tetris. Well, a long time ago, in a galaxy far far away, I was…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Suggested Courses
Course of the Month12 days, 21 hours left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question