Link to home
Start Free TrialLog in
Avatar of Maxmike
Maxmike

asked on

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");
}
ASKER CERTIFIED SOLUTION
Avatar of TascoDLX
TascoDLX

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Maxmike
Maxmike

ASKER

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

Avatar of Maxmike

ASKER

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.
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.
Avatar of Maxmike

ASKER

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.
Avatar of Maxmike

ASKER

hehe, I ended up going with SDL for Dev-C++