DELPHI中汇编语句问题,请高手指点! (100分)

  • 主题发起人 主题发起人 thinknet
  • 开始时间 开始时间
T

thinknet

Unregistered / Unconfirmed
GUEST, unregistred user!
本人不懂汇编,今天在DFW上搜索了一段读硬盘序列号的程序,好多贴子都说明这段程序可
正常编译,但我在编译时却不能正常通过:
提示错误:
[Error] Unit1.pas[75]:lnline assembler syntax error
此错误信息有多条,编辑器第一条语句停在:mov word ptr dd[ecx*2],ax 这条语句上,
而且其它错误语句也都是以MOV开头的汇编语句。

请行家指条道路!!!
 
dd: array [0..256] of word;是全局变量,看看你有没有放错位置。
 
我找到的源程序是这样的:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
type
TGate = record
Off2,op,seg,off1:WORD;
end;

const
_dsnlen=20; //硬盘序列号的位数,10个Word,必须是偶数
_dtplen=40; //硬盘生产厂家型号的位数,18个Word
_dcllen=8; //硬盘控制号的位数

var
IDTR : INT64;
SavedGate : TGate;
OurGate : TGate;
dd : array [0..256] of word;

dsn : array [0.._dsnlen-1] of char; //存放硬盘序列号
dtp : array [0.._dtplen-1] of char; //存放硬盘型号
dcl : array [0.._dcllen-1] of char;

// Ring0 中断服务例程 Ring0Proc ,通过端口读取硬盘参数
procedure Ring0Proc();
asm
// Wait for controller not busy
mov dx,01f7h
@1:in al,dx
cmp al,050h
jne @1

// Get first/second drive
dec dx //mov dx,01f6h
mov al,0a0h
out dx,al

// Get drive info data
inc dx //mov dx,01f7h
mov al,0ech
out dx,al
nop
nop

// Wait for data ready
@2:in al,dx
cmp al,058h
jne @2
nop
nop

// Read sector
xor ecx,ecx
mov dx,01f0h
@3:in ax,dx
mov word ptr dd[ecx*2],ax
inc ecx
cmp ecx,256
jne @3

iretd //中断返回
end;

//改变程序运行的特权级,以调用自定义中断程序 Ring0Proc
procedure Change2Ring0();
asm
mov eax, offset Ring0Proc
mov OurGate.off2, ax //将中断函数的地址填入新造的中断门描述符
shr eax, 16
mov OurGate.off1, ax
mov OurGate.op,0028h
mov OurGate.seg,0ee00h
mov ebx,offset IDTR
sidt [ebx]
//将中断描述符表寄存器(IDTR)的内容取出
mov ebx, dword ptr [IDTR+2]
//取出中断描述符表(IDT)基地址
add ebx, 8*3
//计算Int 3 的描述符应放置的地址选用
//Int3 是因为它在Win32 保护模式下未占用
mov edi, offset SavedGate
mov esi, ebx
movsd //保存原来的Int 9 描述符到SavedGate 以便恢复
movsd

mov edi, ebx
mov esi, offset OurGate
cli
movsd //替换原来的中断门描述符以安装中断服务例程
movsd
sti
mov eax,6200h
//用以测试放在EAX 中的数据能否正确传到 Ring0 中断
mov ecx,0
{用以测试放在 ECX 中的数据能否正确传到 Ring0 中断
因为很多VxD 服务都用此二寄存器传递参数}
int 3h
{人为触发中断, 平时会出现保护错误蓝屏或非法操作对话框,
现在安装了中断服务例程后,
就会通过 VMM 在Ring0 调用中断服务例程Ring0Proc}
mov edi, ebx
mov esi, offset SavedGate
cli
movsd //恢复原来的中断门描述符
movsd
sti
end;

//截取硬盘出厂参数:控制号,型号,序列号
procedure GetParameter;
begin
{硬盘的序列号存放于 dd[10] 开始的10个WORD中,使用时需要将每个WORD的
高低字节颠倒一下}
asm
xor ecx,ecx
mov ebx,offset dd[10*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dsn[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dsn[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dsnlen
jne @1
@2:
end;

{硬盘的型号存放于 dd[27] 开始的18个WORD中}
asm
xor ecx,ecx
mov ebx,offset dd[27*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dtp[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dtp[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dtplen
jne @1
@2:
end;

{硬盘的控制号存放于 dd[23] 开始的3个WORD中}
asm
xor ecx,ecx
mov ebx,offset dd[23*2]
@1:mov ax,[ebx]
cmp ah, 0 //
je @2 //
mov byte ptr dcl[ecx],ah
cmp al, 0 //
je @2 //
inc ecx
mov byte ptr dcl[ecx],al
inc ebx
inc ebx
inc ecx
cmp ecx, _dcllen
jne @1
@2:
end;
end;


end.
 
//---------------------------------
@3: in ax,dx
mov word ptr dd[ecx*2],ax
inc ecx
cmp ecx,256
jne @3
//----------------------------------

由于 dd : array [0..256] of word;
所以这段汇编码这样会造成越界访问内存地址,发生保护错。
依小生之见,应该将
mov word ptr dd[ecx*2],ax
改为
mov word ptr dd[ecx],ax
或者
mov byte ptr dd[ecx*2],ax
 
>>越界访问内存地址,发生保护错
这也应该是程序运行时可能发生的,问题是我现在编译都不能通过,出现上述错误信息。
 
DELPHI中嵌入汇编语句,难道在编译时有什么特殊要求吗?
 
会汇编的DELPHI高手呢?
 
说不定要自己分配内存
FillChar(....);
 
我编译过不了。出现inline assembler syntax error
同一句,我的是6.02
mov word ptr dd[ecx*2],ax
 
我的程序来源于:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=845071
还有DFW上其它许多地方都有这段程序,怎么会在D6下不能编译呢?
 
问题出在你用了dd这个数组名。
要知道在ASM语言中,dd是保留命令字!
把dd数组名改成其它名字就可以了,比如 m_dd

dd : array [0..256] of word; //改成 m_dd: array [0..256] of word;

mov word ptr dd[ecx*2],ax //改成 mov word ptr m_dd[ecx*2],ax;

其它相应的语句也需要改动。

还有就是要注意小生我前面说的内存数据安全性,不然,后果自负。:)




 
TO:kyo_2000
按你所说修改后果然可以编译,但真有你所说的内存数据安全问题吗?
 
看来得回家好好学学汇编了,总觉得搞硬件的人比我们搞软件的更拽一些
 
确实如此。
建议找本汇编的书对照那段代码看看。
也可以看看你编译后有没有warning出现。
祝你好运。


 
接受答案了.
 
后退
顶部