请帮忙修改一个嵌了汇编的Delphi过程(100分)

  • 主题发起人 主题发起人 山药蛋
  • 开始时间 开始时间

山药蛋

Unregistered / Unconfirmed
GUEST, unregistred user!
下面这个过程是我自己编的,目的是读取PortAddr端口的Num个字,存入BuffAddr指定的
地址,这个地址实际是个数组的首地址,BuffAddr应该是个地址指针才对,只是我不知道
该怎么申明,先用Word代了。下面的过程在语法上没错,但不知道寄存器的使用对不对,
应该怎么修改才能正确达到我的目的呢?另外,执行速度是越快越好!谢谢!
procedure ReadPortWFIFO(PortAddr:Word;Num:Word;BuffAddr:Word);
begin
asm
Mov BX,BuffAddr
Mov CX,Num
Mov DX,PortAddr
@1:
In AX,DX
Mov [BX],AX
Inc BX
Loop @1
end;
 
好像有错耶,让俺先去翻翻书。
 
procedure ReadPortWFIFO(PortAddr:Word;Num:Word;BuffAddr:pointer);
//就是pointer
begin
asm
Mov BX,BuffAddr
Mov CX,Num
Mov DX,PortAddr
@1:
In AX,DX
Mov [BX],AX
Inc BX
Loop @1
end;
 
100%的不对
1.在buffaddr是16位的不对,他应是一32位的地址
2.你用的是8086的汇编,你最少需要看一看,80386汇编
3.你是否可以用in % out :在windows 好象只能在特权级下才可使用,即你必须写成VXD
4.你可以用Borland C 3.1试一下,写一个16位的DLL,这好象也是一个方法
 
真是谢谢了!尤其感谢yinxianglong的提醒,但我只在有特权级的系统下(98)运行,
应该是能达到目的的。:P
修改后的程序是这样的,已经能读取数据了,但还有些问题,麻烦大家再给看看:
procedure ReadPortWFIFO(var BuffAddr;PortAddr:Word;Num:DWord);assembler;
register;
begin
asm
Push EBX//寄存器只保存了一个,有什么隐患吗?
Mov EBX,EAX
@1:
In AX,DX
Mov [EBX],AX//这里只写了一个字节,剩下的3字节有非0的
//值就要错了,我对80386的指令集不熟,有没有16位寄存器给64位单元赋值,
//高字节赋0的指令?
ADD EBX,$04
Loop @1
Pop EBX
end;
end;
 
既然只有一個byte,為什麼[ebx]的地方不只定義一個byte/單位的數據區呢?
你在定義變量的時候,有沒有這麼多?經得起add ebx,04....
在定義變量的時候,請初始化一下吧.
一個字節在AL,AH?非要用AX?
in al,dx
mov [ebx],al
...
循環什麼時候結束?
 
你可改成如下:
procedure ReadPortWFIFO(var BuffAddr;PortAddr:Word;Num:DWord);assembler;
register;
asm
PUSH EBX
Mov EBX,EAX
@1:
In AL,DX
Mov [EBX],AL
INC EBX
Loop @1
POP EBX
end;
 
如果在WIN32系统的保护模式下不能进行IN或者OUT指令
则要采用VXD技术或者WDM技术
不过好象有代码可以饶过。
不过我不知道。
另外,如果你想进行32位ASM编程的话,那么则要学会把AX变成EAX
 
不同意ohyee, asm向下兼容的,你当然可以只用16位的ax,或更低的al,只要相应的操作数长度
正确就可以了。ax对应word是没错的。具体要看需要,不一定非得eax
 
关注!帮你提前
 
感谢各位!
太久没上论坛,所以没及时回,抱歉!
to bini:
怪我太懒,没注释清楚。说明补充如下:
先是Delphi参数传递的默认处理:进入汇编代码前,从左到右的三个参数分别被存入
EAX,EDX,ECX,即BufferAddr在EAX,PortAddr在EDX,Num在ECX。ECX中的就是循环次数了。
再就是Integer在内存中占4个字节长度,所以要ADD EBX,$04。
to lorderic:您的修改不能满足我的需要,我是想读字,不是字节,所以用AX,不是AL,
自然,后边的INC EBX由于Integer的限制,也不能用了。
to ohyee:的确有能绕过的方法,但我只是大概看过,没在Delphi下实现。对于EAX,AX的
用法我支持Bluely的观点,呵呵。
 
多少版本的delphi啊。
bx不可思议。。。。
 
我这里没有考虑到硬件响应时间, 用了INSW, 如果硬件速度慢那就只好用 IN AX,DX了
procedure ReadPortWFIFO(PortAddr: Word;
var Buffer;
Count: Integer);
begin
asm
push edi
mov dx, PortAddr;
mov ecx, Count;
mov edi, Buffer;
repnz insw;
pop edi;
end;
end;
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
647
import
I
I
回复
0
查看
711
import
I
I
回复
0
查看
649
import
I
后退
顶部