关于端口访问的问题.........

hdaq 2003-01-13 03:04:03
我有一个程序,由于硬件的要求(没有驱动的数据采集卡,只告知端口定义),需要使用汇编直接端口读写(且只要求在98和ME下使)。于是照书上的方法用了以下函数:

unsigned short inportw(unsigned short port)
{
_DX = port;
__emit__(0x66, 0xED); // 66ED = opcode for in ax,dx
return _AX;
}
void outportw(unsigned short port, unsigned short value)
{
_DX = port;
_AX = value;
__emit__(0x66, 0xEF); // 66EF = opcode for out dx,ax
}

开始时程序能用,程序也正常,并能从采集卡上读取正确的数据。

但是在程序不断增加一些功能的情况下,就出问题了,只要往程序里加一些代码,编译就会出如下问题:
[Tasm Fatal Error] Out of hash space
对应的出错对话筐为:Connot open file d:\bt\main\.
我的prj在d:\bt\main\下,不知道是什么原因?那个"."又是什么意思?

我把以上的汇编换成:
unsigned short inportw(unsigned short port)
{
asm mov dx,port
asm in ax,dx
return _AX;
}

void outportw(unsigned short port, unsigned short val)
{
asm mov dx, port
asm mov ax, val
asm out dx, ax
}
也是一样,把这两个函数中的汇编去掉,就能编译通过。
还有更改Options下Tasm下的Hash也没有用。

不知道要怎样处理?各位大哥大姐帮帮忙,谢过先了。
...全文
65 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Behard 2003-01-14
  • 打赏
  • 举报
回复
学习
meCAD 2003-01-14
  • 打赏
  • 举报
回复
你是访问并口吗?
fatlen 2003-01-14
  • 打赏
  • 举报
回复
找一个叫PORTIO的动态库就行了啊!!
hdaq 2003-01-14
  • 打赏
  • 举报
回复
Adayuer([±0℃])
寄存器用eax,eip ...也是一样....
hdaq 2003-01-14
  • 打赏
  • 举报
回复
还是cker老大牛啊!

1、在我原来的cpp上#pragma inline 是不管用的,如果用(__emit__)的方法,加上#pragma inline就会编译出hash溢出,不用#pragma inline的话就没有问题。

2、我用asm语句时,Tasm选项中改到最大也会出错,可能是我的cpp太大了。

3、将这两个汇编函数单独分开为一个CPP文件竟然也真的可以,不管是用emit还是asm方法。不知道是为什么?

hdaq 2003-01-14
  • 打赏
  • 举报
回复
to fatlen(lion): PORTIO的动态库没用过。
to meCAD() : 不是并口。
  • 打赏
  • 举报
回复
hash表溢出,

1。你试过用#pragma inline 么?
2。调节Tasm编译选项,缺省8192。你可以适当增大这个数值,避免HASH表溢出。
3。将这两个汇编函数单独分开为一个CPP文件就可以了...
halibut 2003-01-13
  • 打赏
  • 举报
回复
32位的没学过,只学过8088/8086的!要学习!
大大怪老张 2003-01-13
  • 打赏
  • 举报
回复
32 位汇编,寄存器用eax,eip ...等.
hdaq 2003-01-13
  • 打赏
  • 举报
回复
谢谢各位大侠
hdaq 2003-01-13
  • 打赏
  • 举报
回复
问题解决了。出在汇编上:
我在文件中加了#include inline,然后使用汇编(即asm{mov,in})进行端口访问,编译时就会出我说的错,把#include inline去掉也不行。

后来用我的第一种方法(__emit__),再把#include inline去掉,竟然成功了。不知道为什么,不过通了就好。

有空还是要仔细看看。
大家也可以继续讨论一下为什么#include inline加了或加了asm{}就会出错?

明天下午结帖。
wjh1014 2003-01-13
  • 打赏
  • 举报
回复
你试试下面的行否!我也没有怎么用过
//---------------------------
void _outp(unsigned short int port, unsigned char value)
{
// mov edx, *(&port);
__emit__(0x8b, 0x95, &port);
// mov al, *(&value);
__emit__(0x8a, 0x85, &value);
// out dx, al;
__emit__(0x66, 0xee);
}
unsigned char _inp(unsigned short int port)
{
unsigned char value;
// mov edx, *(&port);
__emit__(0x8b, 0x95, &port);
// in al, dx;
__emit__(0x66, 0xec);
// mov *(&value), al;
__emit__(0x88, 0x85, &value);
return value;
}
/*
void outportw(unsigned short int port, unsigned short int value)
{
// mov edx, *(&port);
__emit__(0x8b, 0x95, &port);
// mov ax, *(&value);
__emit__(0x66, 0x8b, 0x85, &value);
// out dx, ax;
__emit__(0xef);
}
unsigned short int inportw(unsigned short int port)
{
unsigned short int value;
// mov edx, *(&port);
__emit__(0x8b, 0x95, &port);
// in ax, dx
__emit__(0xed);
// mov *(&value), ax
__emit__(0x66, 0x89, 0x85, &value);
return value;
}
*/
hdaq 2003-01-13
  • 打赏
  • 举报
回复
warton大哥

byte __fastcall ReadByte(WORD Address)
// eax :address
asm
mov DX,AX
in AL,DX
void __fastcall WriteByte
(unsigned char byte, WORD Address)
// EAX: BYTE EDX: ADDRESS
asm
out DX,AL


你的方法和我的方法一样啊!不行的。
warton 2003-01-13
  • 打赏
  • 举报
回复


Win32下的几种串口通信编程


安徽合肥
冯传玉
---- 要完成串口通信, 在32位模式下, 一般说来有以下四种方法:
---- 1. 以文件方式打开串口:
---- 这里使用的是Win32 API 函数, 所以无论在BCB或VC下都可以实现. 具体的函数的
意义可以参考Win32 API 的帮助.这里有一个易于使用的BCB下的类, 可以方便的使用串
口.
---- 下面给出简要说明:
---- (1) 应用CreateFile() 来初始化串口
FhFileComm=CreateFile( FCommName.c_str(),
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
&lpSecurity,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL );
if( FhFileComm == INVALID_HANDLE_VALUE)
return false;
(2) 应用WriteFile() 和 ReadFile() 从串口读写数据
bool MyComm::WriteBuffer(unsigned
char*buffer,unsigned long length)
return WriteFile(FhFileComm,buffer,
length,&length,&FgOverLapped);
bool MyComm::ReadBuffer(unsigned
char*buffer,unsigned long length)
return ReadFile(FhFileComm,buffer,
length,&length,&FgOverLapped);
相应的源文件为 UsageComm.cpp UsageComm.h
---- 2. 使用现成的控件:
---- 易于使用的是微软的MS Communication 控件, 它是做为一个 .ocx 提供的.
---- 在BCB 中可以用Import ActiveX Control 将它加入到BCB 中, 缺省是加载在
ActiveX 页中. 就可以作为一个普通的BCB 控件来使用了.(也有不少第三方提供的其它
硬件操作控件)
---- 3. 直接嵌入汇编法:
---- (该方法不能在NT下使用, 由于98的非完全保护, 下面的代码可以使用)利用BCB的
直接嵌入汇编功能, 可以在BCB中直接对串口操作.
---- 如下所示,在BCB中使用汇编代码如下
byte __fastcall ReadByte(WORD Address)
// eax :address
asm
mov DX,AX
in AL,DX
void __fastcall WriteByte
(unsigned char byte, WORD Address)
// EAX: BYTE EDX: ADDRESS
asm
out DX,AL
---- 这里必须用__fastcall 调用约定以使在调用该函数时用寄存器传递参数.
---- (用在BCB中的汇编指令代码in 和out必须用小写,(其余可以为大写)寄存器名称
大小写都可以)
---- 其它的如写多个字节,读多个字节, 同样可以实现.
---- 4. 最困难的要数用VxD来实现:
---- 这不是一下子能说得清的, 如果要做, 当然要找本书了.
warton 2003-01-13
  • 打赏
  • 举报
回复
你看看option中的设置是否正确!!
hdaq 2003-01-13
  • 打赏
  • 举报
回复
谢谢各位大侠。
据我看来,问题应该出在汇编编译上或编译器上,我想了一下
“Connot open file d:\bt\main\.”这个错误应该是在编译或连接的时候没有找到需要的文件,由此推断,可能在编译时没有生成某个文件....?
jishiping 2003-01-13
  • 打赏
  • 举报
回复
没有用过汇编。
cache2002 2003-01-13
  • 打赏
  • 举报
回复
学习
copy_paste 2003-01-13
  • 打赏
  • 举报
回复
不懂这方面的东东,,,,:(
yuyulily 2003-01-13
  • 打赏
  • 举报
回复
关注。不会,帮你UP。。。
加载更多回复(1)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧