inline asm to C

hi all,

i have this #define in a C code that needs to compile both on 32 and 64
bits,

#define ReadRegister(portnum, offset, readdata) __asm { \
__asm mov dx, portnum \
__asm add dx, offset \
__asm in al, dx \
__asm mov readdata, al \
}

so can someone tell me how to do it. I do not know assembly much so I am
kind of stuck. Good resources online will aso help.

A P wrote:

i all,

i have this #define in a C code that needs to compile both on 32 and
64 bits,

#define ReadRegister(portnum, offset, readdata) __asm { \
__asm mov dx, portnum \
__asm add dx, offset \
__asm in al, dx \
__asm mov readdata, al \
}

so can someone tell me how to do it. I do not know assembly much so I
am kind of stuck. Good resources online will aso help.

If this is a kernel driver, you should be using this instead:
#define ReadRegister(portnum, offset, readdata) readdata =
READ_PORT_UCHAR( portnum+offset )

That does exactly the same thing, in an approved way, and works in
32-bit and 64-bit code.

If it’s in user-mode code, then you must be using some kind of kernel
helper.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

thanks tim, it is kernel mode, and you solved my problem.

best regards

AP

On Fri, Dec 5, 2008 at 6:06 PM, Tim Roberts wrote:

> A P wrote:
> > i all,
> >
> > i have this #define in a C code that needs to compile both on 32 and
> > 64 bits,
> >
> > #define ReadRegister(portnum, offset, readdata) asm { <br>> > asm mov dx, portnum <br>> > asm add dx, offset <br>> > asm in al, dx <br>> > __asm mov readdata, al <br>> > }
> >
> > so can someone tell me how to do it. I do not know assembly much so I
> > am kind of stuck. Good resources online will aso help.
>
> If this is a kernel driver, you should be using this instead:
> #define ReadRegister(portnum, offset, readdata) readdata =
> READ_PORT_UCHAR( portnum+offset )
>
> That does exactly the same thing, in an approved way, and works in
> 32-bit and 64-bit code.
>
> If it’s in user-mode code, then you must be using some kind of kernel
> helper.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

just one other question, this veriosn here

#define ReadRegister(portnum, offset, readdata) __asm { \

__asm mov dx, portnum \
__asm add dx, offset \
__asm in al, dx \
__asm mov readdata, al \
}

puts the offset to be read in dx, in the MACROS there is no provision for
that, so how do I pass the offset?

On Fri, Dec 5, 2008 at 6:20 PM, A P wrote:

> thanks tim, it is kernel mode, and you solved my problem.
>
> best regards
>
> AP
>
> On Fri, Dec 5, 2008 at 6:06 PM, Tim Roberts wrote:
>
>> A P wrote:
>> > i all,
>> >
>> > i have this #define in a C code that needs to compile both on 32 and
>> > 64 bits,
>> >
>> > #define ReadRegister(portnum, offset, readdata) asm { <br>>> > asm mov dx, portnum <br>>> > asm add dx, offset <br>>> > asm in al, dx <br>>> > __asm mov readdata, al <br>>> > }
>> >
>> > so can someone tell me how to do it. I do not know assembly much so I
>> > am kind of stuck. Good resources online will aso help.
>>
>> If this is a kernel driver, you should be using this instead:
>> #define ReadRegister(portnum, offset, readdata) readdata =
>> READ_PORT_UCHAR( portnum+offset )
>>
>> That does exactly the same thing, in an approved way, and works in
>> 32-bit and 64-bit code.
>>
>> If it’s in user-mode code, then you must be using some kind of kernel
>> helper.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
>

#define ReadRegister(portnum, offset, readdata) (readdata) =
READ_PORT_UCHAR((portnum) + (offset))

The parentheses are required as shown.

Note that no assembly code is required, nothing special is required to make
it portable 32/64. This goes back to a serious problem a lot of programmers
have when asking a question: they say “How can I make work?”
when the REAL question is “How do I accomplish this goal?”. You were so
taken up with assembly code (which is completely unnecessary) that you
didn’t ask the question you needed to ask!

No assembly code is required to solve this problem. The whole question
about assembly code is irrelevant. There is no reason to even consider it
as an option.

joe

_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Friday, December 05, 2008 8:53 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] inline asm to C

hi all,

i have this #define in a C code that needs to compile both on 32 and 64
bits,

#define ReadRegister(portnum, offset, readdata)__asm { <br> asm mov dx, portnum <br> asm add dx, offset <br> asm in al, dx <br> asm mov readdata, al <br>}

so can someone tell me how to do it. I do not know assembly much so I am
kind of stuck. Good resources online will aso help.

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

Not quite right. To guarantee correctness, it must be written as

#define ReadRegister(portnum, offset, readdata) \
(readdata) = READ_REGISTER_UCHAR( (portnum) + (offset))

Those extra parens are critical; otherwise the expansion of the parameters
can give unexpected results if any of the parameters is an expression.

The simplified description of the error is

#define Compute(x,y) x * y

Now what is the result of
Compute(3+4, 5+7)

The answer produced is 30, not what you might suspect as 84. The reason is
that it expands to
3 + 4 * 5 + 7

and the result of
2 * Compute(3+4, 5 + 7)
is not 60, or 168, but 33!

2 * 3 + 4 * 5 + 7
is what the compiler sees.

But if you write it as
Compute(x,y) ((x) * (y))

then it will always work correctly.

Learned this the hard way in 1970. Never forgot it.
joe

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Friday, December 05, 2008 9:06 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] inline asm to C

A P wrote:

i all,

i have this #define in a C code that needs to compile both on 32 and
64 bits,

#define ReadRegister(portnum, offset, readdata) __asm { \
__asm mov dx, portnum \
__asm add dx, offset \
__asm in al, dx \
__asm mov readdata, al \
}

so can someone tell me how to do it. I do not know assembly much so I
am kind of stuck. Good resources online will aso help.

If this is a kernel driver, you should be using this instead:
#define ReadRegister(portnum, offset, readdata) readdata =
READ_PORT_UCHAR( portnum+offset )

That does exactly the same thing, in an approved way, and works in
32-bit and 64-bit code.

If it’s in user-mode code, then you must be using some kind of kernel
helper.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

I don’t see what you are talking about. The #define we gave (it turns out I
had answered this independently, with a slightly more correct solution)
definitely handles the case you care about. What “MACROS” are you talking
about?
joe


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Friday, December 05, 2008 9:31 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] inline asm to C

just one other question, this veriosn here

#define ReadRegister(portnum, offset, readdata) __asm { \

__asm mov dx, portnum \
__asm add dx, offset \
__asm in al, dx \
__asm mov readdata, al \
}

puts the offset to be read in dx, in the MACROS there is no provision for
that, so how do I pass the offset?
On Fri, Dec 5, 2008 at 6:20 PM, A P wrote:
thanks tim, it is kernel mode, and you solved my problem.

best regards

AP
On Fri, Dec 5, 2008 at 6:06 PM, Tim Roberts wrote:
A P wrote:
> i all,
>
> i have this #define in a C code that needs to compile both on 32 and
> 64 bits,
>
> #define ReadRegister(portnum, offset, readdata) asm { <br>> asm mov dx, portnum <br>> asm add dx, offset <br>> asm in al, dx <br>> __asm mov readdata, al <br>> }
>
> so can someone tell me how to do it. I do not know assembly much so I
> am kind of stuck. Good resources online will aso help.
If this is a kernel driver, you should be using this instead:
#define ReadRegister(portnum, offset, readdata) readdata =
READ_PORT_UCHAR( portnum+offset )

That does exactly the same thing, in an approved way, and works in
32-bit and 64-bit code.

If it’s in user-mode code, then you must be using some kind of kernel
helper.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

A P wrote:

just one other question, this veriosn here

#define ReadRegister(portnum, offset, readdata) __asm { \
> __asm mov dx, portnum \
> __asm add dx, offset \
> __asm in al, dx \
> __asm mov readdata, al \
> }

puts the offset to be read in dx, in the MACROS there is no provision
for that, so how do I pass the offset?

I showed you that in my example, but a few minutes thought should have
answered this question. Your macro simply builds the port number out of
two pieces: a base and an offset, which are added together. So, add
them together when you call READ_PORT_UCHAR.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.