We help IT Professionals succeed at work.

Convert ASM-Syntax to GCC (PMODE)

Mathias
Mathias asked
on
I want to convert the code from http://www.ata-atapi.com to GCC, but there is a small problem. How can I convert the following procedure to non-assembler. I don't want to use segments and offsets in PMODE so the only thing you have is the *data structure.

OK, here is the source code:

void pio_rep_inword(unsigned int addrDataReg,
                    unsigned int * data,
                    unsigned int wordCnt)
{
     unsigned int dataRegAddr, i;
     //   unsigned int far * uip1;
     //   unsigned int far * uip2;

     dataRegAddr = pio_reg_addrs[ addrDataReg ];
     //   if ( pio_memory_seg )
     //   {
     //      uip1 = (unsigned int far *) MK_FP( pio_memory_seg, dataRegAddr );
     //      uip2 = (unsigned int far *) MK_FP( bufSeg, bufOff );
     //      for ( ; wordCnt > 0; wordCnt -- )
     //      {
     //         * uip2 = * uip1;
     //         uip2 ++ ;
     //      }
     //   }
     //   else
     {
          if ( pio_use_dword && ( ! ( wordCnt & 0x0001 ) ) )
          {
               pio_rep_indword( addrDataReg, data, wordCnt / 2 );
               return;
          }

          asm (
               "pushw  %ax\n"
               "pushw  %cx\n"
               "pushw  %dx\n"
               "pushw  %di\n"
               "pushw  %es\n"

//               "movw   ax,bufSeg\n"
//               "movw   es,ax\n"
//               "movw   di,bufOff\n"

//               "movw   cx,wordCnt\n"
//               "movw   dx,dataRegAddr\n"

//               "cld\n"

//               "rep   insw\n"

               "popw   %es\n"
               "popw   %di\n"
               "popw   %dx\n"
               "popw   %cx\n"
               "popw   %ax\n"
          );
     }
     //   trc_llt( addrDataReg, 0, TRC_LLT_INSW );
}

I hope you can help me. Ask me if you have questions, because i'm very confused with the AT&T asm syntax (why not standard intel?).

Bye, TDS.
Comment
Watch Question

CERTIFIED EXPERT
Author of the Year 2009

Commented:
It looks like that is simply a fn to copy data from a port to a sequence of memory locations.  The core is the:

   rep insw  ; (or insb or insd)

opcode.  This opcode requires setup: You need to set DX to the port number and ES:EDI to the memory location (start of the buffer) and ECX to the count of items (dwords or words or bytes) to transfer.

You cannot do this with *only* C++ (unless the compiler has an extension that I've never heard of).  So you need to use asm.  I don't know what syntax the GCC compiler uses for emitting opcodes -- and the example provides uses a very strange syntax, i agree -- but it looks like this should work:

asm (
    "mov edi,bufOff\n"
    "mov ecx, wordCnt\n"
    "mov dx, dataRegAddr\n"
    "rep insw"
)

Depending upon your compiler, there is a chance that you may also need to set ES (but that is unlikely in any 32-bit scenario).  And depending upon how your compiler generates code, you may also need to save, then restore the registers used.

  "push ecx\n"
  "push edx\n"
  "push edi\n"
  .... the above code here...
  "pop edi\n"
  "pop edx\n"
  "pop ecx\n"

=-=-=-=-
The final code should also provide special handling at the top to see if the bufferlen is not an even multiple of 2 (or 4) and it then does a "short" 1-byte (or 2- or 3-byte) read to finish up.

-- Dan

P.S  Why are you messing around with hard disk device drivers if you don't have a clue about ASM programming?  Just curious.
MathiasIT Specialist

Author

Commented:
I don't program the driver only in asm syntax, the main part is of course in c/c++ syntax. The problem is that I want to use the asm style because it is fast. The code you have posted is not the right thing I want. I want to convert the whole thing to normal c/c++ syntax (not asm). It's slower but I can say that the compiler can understand that in each way. Maybe you can help me like:

while (wordCnt--)
*data++ = inportw(dataRegAddr);

Can this be right? If I use this code my computer hangs because of reading the register too many times. Sometimes it erases parts of my partition table (not good, but I have a recovery disk *g*).

Bye, TDS.
CERTIFIED EXPERT
Author of the Year 2009

Commented:
>>while (wordCnt--)
>>   *data++ = inportw(dataRegAddr);
>>Can this be right?

Yes.  This is right.  Assuming inportw(nPortNum) reads one 16-bit word from i/o port nPortNUm, then this is the correct syntax.

>> If I use this code my computer hangs because of reading the register too many times.

If this is your *real* question, then why did you post the other?  Do you have any idea how irritating that is?

You are likely reading the port too quickly.  If this is the case, REP INSW will also fail.  

From the Intel Instruction Set Reference:
"
Use the REP INS and REP OUTS instructions with caution.
Not all I/O ports can handle the rate at which these instructions execute.
"

Check the hardware reference manual of the hard disk controller.  Odds are, there is a status register that you must read and wait until the busy flag is cleared.  When cleared, you can read the next word (or byte) of data.

-- Dan
MathiasIT Specialist

Author

Commented:
The C-Code is originally for BCC and it works with this compiler. It can't be the "rep" instruction! Look at the code at ata-atapi.com and say me why it doesn't really work under GCC? Is there already a GCC port? I can post my code to show you how far I am. If I do this I will increase the points, but only if the code works well.
Are you interested in such a thing (I know that's not my real question)?

Bye, TDS.
CERTIFIED EXPERT
Author of the Year 2009

Commented:
Please don't post your code.

Your problem is not porting to a different compiler.  It is that the existing code is 16-bit code and this is a 32-bit world.  Even if you could get the code to compile, you will be miles away from having a device driver that will be useful for anything.

-- Dan
MathiasIT Specialist

Author

Commented:
Yes, but only this asm statement is the point. if I can program it to work correct I think the 16bit don't causes problem even with a 32bit compiler. I saw many programs which are working with 16bit and 32bit perfectly, so why should my program work wrong?

Bye, TDS.
CERTIFIED EXPERT
Author of the Year 2009

Commented:
>>I saw many programs which are working with 16bit and
>> 32bit perfectly, so why should my program work wrong?

I think this may be a little bit hard to explain.  perhaps if you start with this:

A HARDWARE DEVICE DRIVER IS THE MOST DIFFICULT AND COMPLEX PIECE OF SOFTWARE THAT IT IS POSSIBLE TO WRITE.  It is intimate with the hardware at a much lower level than any of the "hello world" programs that you have seen before.

It will need to connect into the 32-bit operating system which will have no means whatsoever to communicate with its 16-bit code.

Other than that, I see no problem.

-- Dan
MathiasIT Specialist

Author

Commented:
My code should work in an environment which has full access to everything in the PC. That is ring 0 in the kernel interface. The kernel interface works under BasicOS, a new operating system I work on with some others. That means that the code, which is working under REAL MODE, should work under BasicOS as well. The only problem is that function with segment and offset, because you access it in PMODE in that way too, but it is too complicated so I want to have this in a mode-independent way.

Bye, TDS.

Commented:
I think you forgot this question. I will ask Community Support to close it unless you finalize it within 7 days. Unless there is objection or further activity,  I will suggest to accept "DanRollins" comment(s) as an answer.

If you think your question was not answered at all, you can post a request in Community support (please include this link) to refund your points.
The link to the Community Support area is: http://www.experts-exchange.com/commspt

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
======
Werner
MathiasIT Specialist

Author

Commented:
griessh: The code wasn't translated to work yet. Every time i tested it the app crashed :-( Today i'm using my own written driver. If within a week no real answer will be published i will delete this question by myself.

Bye, TDS.
Force accepted

** Mindphaser - Community Support Moderator **

Explore More ContentExplore courses, solutions, and other research materials related to this topic.