如何在VC++6.0中嵌入汇编语句?

fieldmouse 2000-11-23 10:45:00
本人在VC++6.0中用如下语句读软盘引导扇区:
char a[512];
UINT p=(UINT)a;
_int8 flag=0;
_int16 seg,off;
seg=HIWORD(p);
off=LOWORD(p);
_asm
{
mov AX,seg
mov ES,AX
mov BX,off
mov AH,02H
mov DL,00
mov DH,00
mov CH,0
mov CL,1
mov AL,1
INT 13H
mov flag,CY
}
if(flag)
MessageBox("Read sector ok!");
编译时出错,提示为:
(mov ES,AX句)error C2400:inline assembler syntax error in 'second operand'; found 'newline'
(}句)error C2415: improper operand type
请高手帮忙看看哪儿不对。
谢谢!
...全文
569 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fieldmouse 2000-11-28
  • 打赏
  • 举报
回复
多谢各位大哥!!!!!!
kevincheng 2000-11-27
  • 打赏
  • 举报
回复
这应该是属于对硬件直接读写的操作,系统是禁止的。
ivefire 2000-11-27
  • 打赏
  • 举报
回复
进入后先要保存各寄存器的值,退出前恢复.
Tasehouny 2000-11-27
  • 打赏
  • 举报
回复
想读磁盘的绝对扇区,这个简单,给你一段我用过的代码。
// Bios.h: interface for the CBios class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_BIOS_H__D25E5BB1_5B1F_11D4_BF46_00E04C800DD8__INCLUDED_)
#define AFX_BIOS_H__D25E5BB1_5B1F_11D4_BF46_00E04C800DD8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CBios
{
public:
int FormatDisk(int head,int track,int sector);
int Virefy(int head,int track,int sec);
int GotoTrack(int track);
int ResetDisk(void);
int WriteSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer);
int ReadSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer);
int MakeSector(unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char *buffer);
CBios();
virtual ~CBios();

protected:
int WinBiosDisk(unsigned char command,unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char nsectors,void *buffer);
// int WinReadDisk(unsigned char drive,unsigned char sector,unsigned char nsectors,void *buffer);
};

#endif // !defined(AFX_BIOS_H__D25E5BB1_5B1F_11D4_BF46_00E04C800DD8__INCLUDED_)



#include "stdafx.h"
#include "Bios.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*本代码用到了 周化同志 写的软盘扇区绝对读取函数 WinBiosDisk()


为了方便, 本函数的参数设计得同 Turbo C 2.0 的 biosdisk() 函数一样.

本函数还有以下两个缺点以待改进:
1.本函数还只能读能读 A: 和 B:,即只能对软盘操作
2.不能改变磁盘扇区大小,只能是标准的 512 个字节。

参数说明:
command 操作:
0 重置磁盘
2 读扇区
3 写扇区
4 校验磁道
5 格式化磁道
8 得到设备参数 (int 1EH)
drive 驱动器 A:=0 B:=1
head 磁头号,范围 0 - 1
track 磁道号,范围 0 - 84 ( 80 - 84 为特殊磁道,通常用来加密 )
sector 扇区号,范围 0 - 255 ( 19 - 255 为非标准扇区编号,通常用来加密)
nsectors 每次读或写的扇区数,不能超出每磁道的最大扇区数
buffer 数据写入或读出的缓冲区,大小为 512 个字节

返回值 ( 同 Int 13H ):

0x0 成功
0x1 无效的命令
0x3 磁盘被写保护
0x4 扇区没有找到
0xa 发现坏扇区
0x80 磁盘没有准备好

******************************************************************/

CBios::CBios()
{

}

CBios::~CBios()
{

}

int CBios::WinBiosDisk(unsigned char command,unsigned char drive,unsigned char head,unsigned char track,unsigned char sector,unsigned char nsectors,void *buffer)
{
HANDLE hd;
DWORD dw;

//int13 寄存器参数块
typedef struct tagPackage
{
void *buffer; // ebx 寄存器

unsigned char drive; // edx 寄存器
unsigned char head; //
unsigned short edx_high; //

unsigned char sector; // ecx 寄存器
unsigned char track; //
unsigned short ecx_high; //

unsigned char number; // eax 寄存器
unsigned char option; //
unsigned short eax_high; //

unsigned int edi; // edi 寄存器

unsigned int esi;
unsigned int eflag;
} PK;

PK pk;
memset(&pk,0,sizeof PK);
pk.buffer=buffer;
pk.drive=drive;
pk.head=head;
pk.sector=sector;
pk.track=track;
pk.option=command;
pk.number=nsectors;

if(command==0x18)pk.edi=(int)buffer;
hd=CreateFile("\\\\.\\vWin32",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
if(hd==NULL)return 1;
DeviceIoControl(hd,4,&pk,0x1c,&pk,0x1c,&dw,NULL);
if(command==0x8)memcpy(buffer,(unsigned char *)pk.edi,11);
CloseHandle(hd);
return pk.option;

}

/*
int CBios::WinReadDisk(unsigned char drive, unsigned char sector, unsigned char nsectors, void *buffer)
{

}
*/
int CBios::MakeSector(unsigned char drive, unsigned char head, unsigned char track, unsigned char sector, unsigned char *buffer)
{
int i,ret,retry;
unsigned char ctemp[513],cmd[3]={5,3,2};
for(i=0;i<3;i++)
{
retry=5;
while(retry)
{

if(i==0)
{ctemp[0]=track;
ctemp[1]=head;
ctemp[2]=sector;
ctemp[3]=2;
}
else if(i==1)
memcpy(ctemp,buffer,512);
ret=WinBiosDisk(cmd[i],drive,head,track,sector,1,ctemp);
if(ret==0)break;
else if(ret==0x3)return ret;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,ctemp); //重置磁头
retry--;
}
if(!retry)return ret;
}
ret=memcmp(ctemp,buffer,512);
if(ret)return 0xffff;
else return 0;
}

int CBios::ReadSector(unsigned char drive, unsigned char head, unsigned char track, unsigned char sector, unsigned char *buffer)
{
int i,retry=5;
while(retry)
{
i=WinBiosDisk(2,drive,head,track,sector,1,buffer);
if(i==0)break;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer); //重置磁头
retry--;
}
return i;

}

int CBios::WriteSector(unsigned char drive, unsigned char head, unsigned char track, unsigned char sector, unsigned char *buffer)
{
int i,retry=5;
char *buffer1;
buffer1=new char[8196];
while(retry)
{
i=WinBiosDisk(3,drive,head,track,sector,1,buffer);
if(i==0)break;
WinBiosDisk(2,drive,head,track?track-1:track+1,sector,1,buffer1); //重置磁头
retry--;
}
delete []buffer1;
return i;

}

int CBios::ResetDisk()
{
char *buff;
buff = new char[8196];
int i;
i = WinBiosDisk(0,0,1,1,1,1,buff);
delete []buff;
return i;
}

int CBios::GotoTrack(int track)
{
char *buff;
buff = new char[8196];
int i,retry = 5;
int h,sec;
while(retry)
{
h = rand()%2;
sec = rand()%18;
i = WinBiosDisk(4,0,h,track,sec,5,buff);
if(i==0)break;
retry--;
}
delete []buff;
return i;
}

int CBios::Virefy(int head, int track, int sec)
{
int i,retry=5;
char *buff;
buff=new char[8196];
while(retry)
{
i=WinBiosDisk(4,0,head,track,sec,1,buff);
if(i==0)break;
WinBiosDisk(2,0,head,track?track-1:track+1,sec,1,buff); //重置磁头
retry--;
}
delete []buff;
return i;
}

int CBios::FormatDisk(int head, int track, int sector)
{
BYTE buf[1024];
for(int i= 0;i<1024;i++)
{
buf[i] = 0xF6;
}
// char *buff =(char*)buf;
int err = MakeSector(0,head,track,sector,buf);
return err;
}
xyzhao 2000-11-27
  • 打赏
  • 举报
回复
VC6编译出来的程序运行在3环的32位程序,好像不能直接操作段寄存器ES,还有能不能调用软中断,既不太清楚了,你要是想知道给我发封信我给你查查资料。
又,在Win32程序中调用dos中断有专门的方法,似乎不能直接用汇编调用。你可以自己到msdn里去研究一下相关文档
Platform SDK
Win32 API
Windows 95/98 Programming
Windows 95/98 Overviews
Device I/O Control
About Device I/O Control
Using VWIN32 to Carry Out MS-DOS Functions
fieldmouse 2000-11-26
  • 打赏
  • 举报
回复
kevincheng,谢谢你的帮助。我按你的意见修改程序后,编译能通过,但一执行就非法操作,能再给点建议吗?
kevincheng 2000-11-24
  • 打赏
  • 举报
回复
不好意思,错了点.
mov ax,segm
push ax
pop es
kevincheng 2000-11-24
  • 打赏
  • 举报
回复
char a[512];
UINT p=(UINT)a;
_int8 flag=0;
_int16 segm,offm;
segm=HIWORD(a);
offm=LOWORD(a);
_asm
{
push es
;
mov ax,segm
pop es
mov ax,0201h
mov bx,offm
mov cx,1
mov dx,0
int 13h
mov flag,ah
;
pop es
}
if(flag)
MessageBox("Read sector ok!");
ivefire 2000-11-24
  • 打赏
  • 举报
回复
seg在VC++中属于保留字,你用segm就没事了。mov flag,CY应改为mov flag,AH
dingsg 2000-11-24
  • 打赏
  • 举报
回复
_asm
sxbyl 2000-11-24
  • 打赏
  • 举报
回复
我记得是用AX返回值的吧?还是CX?好几年了,都忘了。
sxbyl 2000-11-24
  • 打赏
  • 举报
回复
CY ? 有这个寄存器吗?
sun2000 2000-11-23
  • 打赏
  • 举报
回复
是seg和off的原因你查一下帮助吧
一、 实验目的和要求 掌握VC++语言和汇编语言的混合编程方法,了解不同编程语言的接口方法,体会汇编语言的应用。 掌握嵌入汇编函数和汇编语言子程序与VC++的混合编程方法,入口、出口参数的传递方法以及在VC++环境下混合编程的调试方法。 二、 实验条件 硬件:计算机一台 软件:Visual Studio C++ 6.0、MASM 6.0 三、 实验原理分析 在Turbo C++或Borland C++编程环境下,我们可TCC或BCC行命令把一个C语言的源程序转换成汇编语言的源程序。通过阅读汇编语言程序可以很准确地知道C语言语句的功能是如何实现的。 C语言源程序转换的命令格式如下: TCC -S t1.c 或 BCC -S t1.c   ;假设其文件名为t1.c 注意:(1)TCC在TC目录下,若命令TCC/BCC不带参数的话,则将显示其使用方法。 (2)其-S要求S为大写。 (3)在TC上做以上操作,必须保证:TC正常安装(c:\turboc2),目录名及文件夹名都不能改变。 下面是C语言程序及其相对应的汇编语言程序,希望读者能逐行对照理解它们语句之间的转换关系,这将能进一步理解高级语言的语句功能。 (4) 汇编语言和高级语言混合编程,需要解决两个主要的技术问题: 不同语言程序模块之间的连接; 调用过程参数的传递方法。 对此不同的高级语言或同一种高级语言的不同版本所采取的具体方法不尽相同。本节主要介绍汇编语言与C/C++语言接口的基本方法。 调用协议是指在进行子程序调用时,主程序向子程序传递参数以及从子程序获得返回值的约定方式。 通常参数传递的方法是:主程序使用系统堆栈向子程序传递入口参数,子程序使用CPU内部寄存器来保存向主程序的返回值。此外调用协议还将确定哪些寄存器的内容需要保护,哪些寄存器可以自由使用。

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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