为什么没人回答这个问题(I/O口读写)(135分)

  • 主题发起人 主题发起人 basket
  • 开始时间 开始时间
B

basket

Unregistered / Unconfirmed
GUEST, unregistred user!
我删除了原问题,倾囊再问
我在各处看见两种写I/O口的程序
1)procedure outportb(Address:Word;
Data:Byte);assembler;asm
MOV DX,Address MOV AL,Data
OUT DX,ALend;
function inportb(Address:Word):Byte;assembler;asm
MOV DX, Address IN AL,DXend;
2)//读取指定端口的数据function inp(port : integer) : integer;
begin
asm
mov edx,port xor eax,eax in al,dx mov result, eax
end;
end;
//往指定端口上发送数据procedure outp(port,value : integer);
begin
asm
mov edx,port mov eax,value out dx,ax end;
end;

它们是否都能用?如果是,为什么1)中的inportb没有类似Result:=...的语句?
 
马马虎虎能用的,不完整。
我用的是BCB,Delphi一样都支持内嵌汇编语言的实现,你自己改变一下吧。
(已经应用到工程中)。
/*在文件头加一句#pragma inline,允许内嵌汇编*/
#pragma inline
void outportb(unsigned short int portnum, unsigned char value)
{
asm{
push dx
push ax
mov dx,portnum
mov al,value
out dx,al
pop ax
pop dx
}
}
/******************************************************************/
void outportw(unsigned short int portnum, unsigned short int value)
{
asm{
push dx
push ax
mov dx,portnum
mov ax,value
out dx,ax
pop ax
pop dx
}
}
/******************************************************************/
unsigned char inportb(unsigned short int portnum)
{
unsigned char value;
asm{
push dx
push ax
mov dx,portnum
in al,dx
mov value,al
pop ax
pop dx
}
return value;
}
/******************************************************************/
unsigned short int inportw(unsigned short int portnum)
{
unsigned short int value;
asm{
push dx
push ax
mov dx,portnum
in ax,dx
mov value,ax
pop ax
pop dx
}
return value;
}
/******************************************************************/
 
我的主要疑问是,除了PUSH和POP外,是不是在inportb的最后应加一句
MOV RESULT, AL
原来的inportb是:
function inportb(Address:Word):Byte;assembler;
asm
MOV DX, Address
IN AL,DX
end;
 
Delphi里嵌套汇编好象编译时会给你加 push,pop的,不用自己动手
应该有 in result,al
 
inportb最后要有 MOV RESULT, AL
原来程序漏了
inp代码中的 in al,dx
应该改为 in ax,dx
刚才没有仔细看
 
在Delphi中汇编函数返回一个字节存在AL中一个字在AX中一双字在EAX中,不需
要用mov result, AL
 
谢谢各位,最终可用的还是原来的版本:
function inportb(Address:Word):Byte;assembler;asm
MOV DX, Address
IN AL,DX
end;

但是outportb出问题了,
procedure outportb(Address:Word;
Data:Byte);assembler;asm
MOV DX,Address
MOV AL,Data
OUT DX,AL
end;

我将inportb和outportb放在一个Unit中,然后在另一个Unit中调用,如果我按照
上面的写法,单步执行的结果是DX中置入了Address值,但AL中没有置入Data值。
如果我将两句Mov指令对调,
MOV AL,Data
MOV DX,Address
OUT DX,AL
那么单步执行的结果是AL中置入了Data值,但DX中没有置入Address值。即两句
Mov中只有第一句是对的。WHY?
最后我的解决办法是取消了outportb这个过程,直接将这几句汇编写入程序,这样
才对,有人知道原因吗?
 
试一下这个:
procedure outportb(Data:Byte;Address:Word);assembler;asm
OUT DX,AL
end;

xixi,好玩吧,Delphi默认的调用方式用寄存器串参数!
 
难道你没注意我原来的回答?
1)asm的function自动返回ax的,所以不需要赋值result
2)你的outportb之所以不能用,是因为asm不能正确传递值参
你可以象我的例子里那样,先赋值给一个本地变量,再联编嵌入asm
当然你的函数声明就不能是assembler了
 
to: iie
你是对的,抱歉没仔细看你的代码!
在原来的问题
(http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=195810)中
有些回答用到了outportb那个函数,我只是想说一下它不能用的原因
对于你第二点,我觉得如果能按照delphi默认的方式,把变量传到寄存器中并直接
使用,效率会是最高的(我不知现在编程还讲不讲效率)。
 
我做一下我自己的理解,这可能与函数的声明有关:
例如
Function PortReadWord(Addr:Word):word;Assembler;register;
begin
mov dx,ax
in ax,dx
end;
就不需要mov result,ax,因为程序会从寄存器中直接读返回值。而下面:
Function PortIn(Addr:word):Byte;
begin
asm
mov dx,Addr
in al,dx
mov result al
end;
end;
就必须要有最后的语句,因为这是用内嵌函数的形式调用汇编,使用的是不同的堆栈
必须将寄存器中的值返回给调用的函数,否则将不会得到结果。
 
to iee:
不知你指的原来的回答在哪儿?
能再贴一下你的例子吗?
或者有谁能贴一个最终能用的版本?我都胡涂了
 
这些方法在DELPHI的高版本可以使用吗?
好象使用汇编在DELPHI3。0以后就只能对
标准I/O口操作。
建议使用控件:SmallPort。
采用的是虚拟设备方式,任何版本都
有效。
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
542
import
I
I
回复
0
查看
728
import
I
I
回复
0
查看
631
import
I
I
回复
0
查看
645
import
I
I
回复
0
查看
681
import
I
后退
顶部