stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1925回复:14

关于READ_PORT_UCHARR的一个问题?

楼主#
更多 发布于:2002-10-03 17:15
我想读一下并口(0x378)上的数据,但是如果读的是字节的话,它的端口号用的是PUCHAR,它的最大值应该是0xff,装不下0x378,应该怎么办?
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-10-03 17:43
我想读一下并口(0x378)上的数据,但是如果读的是字节的话,它的端口号用的是PUCHAR,它的最大值应该是0xff,装不下0x378,应该怎么办?


应该有READ_PORT_WORD(SHORT?),READ_PORT_ULONG等的东东吧。

 :o
[color=red]大头鬼! :P[/color]
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-10-03 19:20
[quote]我想读一下并口(0x378)上的数据,但是如果读的是字节的话,它的端口号用的是PUCHAR,它的最大值应该是0xff,装不下0x378,应该怎么办?


应该有READ_PORT_WORD(SHORT?),READ_PORT_ULONG等的东东吧。

 :o [/quote]

是有呀
但是读出来的也是SHORT和ULONG类型的嘛
我只要UCHAR类型的

是不是必须要用这种函数,然后取读出来数据的低部分?
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-10-04 14:40
PUCHAR是一个指针,在32位系统中它的取值范围是:
0 ~ 0xFFFFFFFF,而不是0 ~ 0xFF
archim
lily311
驱动小牛
驱动小牛
  • 注册日期2002-08-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望26点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-10-04 16:21
PUCHAR是一个指针,在32位系统中它的取值范围是:
0 ~ 0xFFFFFFFF,而不是0 ~ 0xFF


archim说的是对的.
所以尽管用READ_PORT_UCHAR(8 bits)好了.
千万不要用READ_PORT_USHORT(16 Bits),READ_PORT_ULONG(32 Bits)来读取一个byte(8 Bits).
比如说,你本来要往端口写一个8 bits的数据0x12,如果用WRITE_PORT_UCHAR就对了.如果用READ_PORT_USHORT,它其实会写Ox12和0x00两个数据.读数据也是类似.如果只取后8位,会漏掉8位数据(其实已经被读出来了).

我今天刚刚验证并解决这个问题,呵呵.
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-10-04 18:58
PUCHAR是一个指针,在32位系统中它的取值范围是:
0 ~ 0xFFFFFFFF,而不是0 ~ 0xFF


偶将汇编中的端口东东,混起来了。

 :( :( :(

[color=red]大头鬼! :P[/color]
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-10-04 19:45
我明白了
谢谢各位
给分了
不过只有这么点
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-10-05 09:07
READ_PORT_UCHAR的原型为:

UCHAR
  READ_PORT_UCHAR(
  IN PUCHAR  Port
  );

这里Port就是想要读取的端口号,它的取值从理论上应该是0 ~ 0xFFFFFFFF,但是由于80x86只支持16位的端口,因而它的取值只有在0 ~ 0xFFFF之间才有意义。

返回值为UCHAR,表明函数的功能是读取从Port开始的8位端口的值,该返回值的取值范围才是0 ~ 0xFF

举个例子:
READ_PORT_UCHAR(0x378)将读取端口0x378的值
READ_PORT_USHORT(0x378)则读取端口0x378, 0x379的值
READ_PORT_ULONG(0x378)则读取端口0x378, 0x379, 0x37A, 0x37B的值。

当然,你用READ_PORT_ULONG来代替READ_PORT_UCHAR应该是没有什么问题的。只不过READ_PORT_ULONG先读取一个32位端口的值,在赋值的时候C语言会进行自动类型的转换。

但是你绝不能用WRITE_PORT_ULONG来代替WRITE_PORT_UCHAR,如WRITE_PORT_ULONG(0x378, xxxxx),那么不仅端口0x378的值改变了,连0x379, 0x37A, 0x37B的值都会改变的。

READ_PORT_UCHAR的反汇编代码为:

xor eax, eax
mov edx, [esp+4] ; Port
in al, dx ; 如果是READ_PORT_USHORT则为 in ax, dx
          ; READ_PORT_ULONG则为in eax, dx

ret 04

这样你也许更容易理解
archim
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-10-05 16:26
我是这样做的
在device extension里有一个ushort类型的成员,保存0x378,到读端口时强制转换成puchar,用softice跟踪得到的值为0x78(断点设在read_port_uchar那里),而且读出来的数据与用其它测试过的软件读得的数据比较是完全不同的。
 
READ_PORT_UCHAR的反汇编代码为:

xor eax, eax
mov edx, [esp+4] ; Port
in al, dx ; 如果是READ_PORT_USHORT则为 in ax, dx
; READ_PORT_ULONG则为in eax, dx

ret 04

这样你也许更容易理解




这样子我是明白了好多,但是如果照这样的汇编代码的话,为什么象我那样做不对呢?
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-10-05 16:43
 
READ_PORT_UCHAR的反汇编代码为:

xor eax, eax
mov edx, [esp+4] ; Port
in al, dx ; 如果是READ_PORT_USHORT则为 in ax, dx
; READ_PORT_ULONG则为in eax, dx

ret 04

这样你也许更容易理解


 


如果按这样的汇编代码,在READ_PORT_UCHAR被调用的时候,edx寄存器应该是0x378,但是我看到的却是00000078,好象有点不对吧。

看一下我相关的代码有什么不对。
*puChar = READ_PORT_UCHAR ((PUCHAR)(pdx->usPortBase + DATAPORT));
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-10-05 16:51
[quote]READ_PORT_UCHAR的反汇编代码为:

xor eax, eax
mov edx, [esp+4] ; Port
in al, dx ; 如果是READ_PORT_USHORT则为 in ax, dx
; READ_PORT_ULONG则为in eax, dx

ret 04

这样你也许更容易理解


 


如果按这样的汇编代码,在READ_PORT_UCHAR被调用的时候,edx寄存器应该是0x378,但是我看到的却是00000078,好象有点不对吧。

看一下我相关的代码有什么不对。
*puChar = READ_PORT_UCHAR ((PUCHAR)(pdx->usPortBase + DATAPORT)); [/quote]

改为:

*puChar = READ_PORT_UCHAR ((PUCHAR)(&(pdx->usPortBase)) + DATAPORT); [/quote]


[color=red]大头鬼! :P[/color]
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-10-05 17:09
读取端口0x378开始的8位数据的C语言代码应该是:

PUCHAR Port;
UCHAR PortVal;

Port = (PCHAR)0x378;
PortVal = READ_PORT_UCHAR(Port);

我觉得这个函数的使用容易引起混淆主要是因为参数Port的类型定义为PUCHAR,如果将函数的定义改成:

UCHAR
  READ_PORT_UCHAR(
  IN ULONG Port // 端口号
  );

相信就不会有那么多的疑问了。
archim
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-10-05 17:33
哦,我范了一个低级的错误。
archim,不好意思啦。不是我不相信你,只是还没有解决问题的嘛。
lily311
驱动小牛
驱动小牛
  • 注册日期2002-08-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望26点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-10-07 09:30
我的代码是:

typedef struct PCT_READ_PORT_
{
unsigned short port;
} PCT_READ_PORT, *PPCT_READ_PORT;

typedef struct PCT_READ_CHAR_
{
unsigned char datachar;
} PCT_READ_CHAR, *PPCT_READ_CHAR;

 
      case IOCTL_UCHAR_READ:
PPCT_READ_PORT pInBuf = (PPCT_READ_PORT)ioBuffer;
UCHAR data = READ_PORT_UCHAR((PUCHAR)pInBuf->port);
PPCT_READ_CHAR pOutBuf = (PPCT_READ_CHAR)ioBuffer;
pOutBuf->datachar = data;
stoneyr
驱动牛犊
驱动牛犊
  • 注册日期2002-01-13
  • 最后登录2007-10-31
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-10-07 15:33
好的,谢谢各位了。现在我已经解决问题了。我觉得也应该这样定义原型比较好:
 
UCHAR
READ_PORT_UCHAR(
IN ULONG Port // 端口号
);


那个参数不应该是PULONG,这样就好了。
游客

返回顶部