★★★★★★VC中用汇编的问题!!!(很菜的!!!)★★★★★★

时间:2022-06-14 11:55:27
小弟我正在学习“微机原理与接口技术”课

现在正好讲到“怎么将ASM与C/C++起用”

书上说,有两种方式:

1。内联(in-line)
 就是用_asm{}的方法
2。单独写成汇编模块,再一起联接。
==================================
 我有些不明白:
 1)书上说有些寄存器不用“保护”,比如AX(EAX),BX(EBX)等等。
  因为那本书用的是VC4.2,不知道现在VC6的规定有没有什么变化?
 2)关于“实”模式和“保护“模式编程的问题:
  16-bit Applications是不是就是“实”模式下的程序?
  而32-bit Applications是不是就是“保护”模式下的程序呢?
  或者说,只能用AX,BX的就是“实”的?
  能用EAX,EBX的就是“保护”的?

  那么,我在“Win32 Console Application”下编程是不是就是在“实”模式下编程呢?而在“Win32 Application”或者在“类向导”下是不是就是“保护”模式呢?
 3)在“单独汇编模块”中,书上有这么一个程序:
 ============
  .386
   .model flat,c
   .stack 1024
   .code
   
   public Reverse
   Reverse proc uses esi,\
   arraychar:ptr
   
  mov esi
   push 0 //???
   .repeat
   mov al,[esi]
   ...
   ...
   end
 ======================
为什么有一个"uses esi"呢?程序中还用到其他寄存器了呀?为什么没有提起?
另:.386表示是32位程序吗?也就是”保护模式”?
还有,那个“续行符”是什么意思?把下一行的“arraychar:ptr”提上去,而不用'\'可以吗?
   

=================================================================
  很菜的问题,可是我真的很想知道!!!

  请大家帮助!
  人多我再加分!

35 个解决方案

#1


我加到100分了,回答多少给多少分!

UP者有分!

#2


关注

#3


我正在试验,看来我想错了。

即使是VC6下的“Win32 Console Application”,默认也是32位的!!!

因为我无法调用DOS中断!

书上说应该禁止"Windows foundation class libraries”
可是怎么做呢?

我去看Project中的Setting了,有很多lib呀!
应该禁用哪些呢?

#4


1)书上说有些寄存器不用“保护”,比如AX(EAX),BX(EBX)等等。
  因为那本书用的是VC4.2,不知道现在VC6的规定有没有什么变化?

    VC6里边EAX,EBX也可以在汇编里直接用,其他寄存器最好先PUSH一下,用完了再POP

 2)关于“实”模式和“保护“模式编程的问题:
  16-bit Applications是不是就是“实”模式下的程序?
  而32-bit Applications是不是就是“保护”模式下的程序呢?
  或者说,只能用AX,BX的就是“实”的?
  能用EAX,EBX的就是“保护”的?

    不一定,windows下的DOS程序兼容用的是V86模式,并且实模式也可以用386指令和寄存器

3)
 为什么有一个"uses esi"呢?程序中还用到其他寄存器了呀?为什么没有提起?
另:.386表示是32位程序吗?也就是”保护模式”?
还有,那个“续行符”是什么意思?把下一行的“arraychar:ptr”提上去,而不用'\'可以吗?

   .386表示使用80386指令集,不一定是保护模式
   可以把下一行提上去而不用'\'

#5


在Win32里实模式与保护模式都是32位,Win32 Console Application 应该可以调用dos中断。

#6


。386表明使用的处理器,保护模式和实模式,protected mode and real mode,只是一种cpu的工作状态,保护模式可以提供一个4gb的可直接寻址的方式,每个程序都可以这样,而实模式并不能提供,关于这个方面的可以参考intel的处理器说明,mode flat,就表明使用的是保护模式了。
对于寄存器的使用,一般来说是没有限制的,ax,eax,都可以使用,只不过位数不一样而已。
console application 在winnt/2000下是没有办法调用中断的,这个是由于操作系统的原因,当然有些特殊的办法可以绕过去,还是用win98吧。
mfc的禁用在console下面都是禁用的,除非你选择使用才有可能。

#7


To wacky(笨笨狗):
不行的。
我试了,不能调用,不信,你可以试:

void main(void)
{
_asm
{
mov ah,8
int 21h
cmp al,'0'
jb big
cmp al,'9'
ja big
mov dx,ax
mov ah,2
int 21h
}
big: {;}
}

还有,按照你的说法,“16位”程序不一定就是“实”模式程序,
而“32”位程序不一定就是“保护”模式了?

那怎么控制是“实”的还是“保护”的呢?

#8


请说明,

要使用嵌入式汇编的目的,

如果要写Vxd建议你用专门的开发工具VToolsD,

要读写端口请进www.internals.com网站,下载WinIO库,

该库可以在Win9x/2000/xp下面屏蔽掉Windows的硬件保护机制,甚至于guest

登陆方式都可以直接访问硬件。

我认为只有要进行算法执行速度优化时,才应该考虑使用嵌入式汇编,

可以这样说,凡是使用嵌入式汇编实现的功能,使用正常“高级”方式都可

以实现。

#9


To zhakewei(天外有天):

我用的是win98,可还是不能调用DOS中断呀!

还有,应该不是“禁用MFC”,书上说是:“Windows foundation class libraries”

WFC?没听说过。

还有,mode flat表明是保护模式?那就是说,系统默认是“实”模式吧?

#10


To serverclient(郁闷)

谢谢你的建议。可是我现在是在“学习”,没有考虑其他因素。

我只是想搞懂而已。

希望你能帮助我

多谢

#11


UP

#12


to:cywater2000(如果) 


1。不要用VC来写“16位实模式汇编语言”
VC只能一个编辑界面,它能够正确运转,是依赖于它的link.exe等等文件的,说白了,VC什么都是不是,只是提供一个界面,来帮助程序员摆脱“命令行编译”的困境

2。在VC编辑环境下,C/CPP文件中使用了内嵌汇编代码,编译时,同样还是当作“32位保护模式”来编译的,因为VC缺省使用的编译器都是32位的!!!(这些文件在Microsoft Visual Studio\Common\MSDev98\Bin\下)所以,“Win32 Console Application”还是32位保护模式的,千万不要看见“黑底白字”就以为是DOS程序,就是16位实模式程序。

3。在阐述汇编语言时,“什么样的模式”和“16位还是32位”,是不能分开的!汇编语言有“16位实模式”“16位保护模式”“32位保护模式”几种,所以,仅仅是一个“16位汇编”,是不能说明任何问题的

4。综合你的情况,建议:直接使用汇编,MASM 6.1,或者TASM5,都可以,它们编译出来的就肯定是“16位实模式”,是肯定能调用“DOS中断”的。但是,要注意一点,WIN98下的运行的DOS程序,是“虚拟机”模式的。而16位实模式程序在NT/W2K下根本不能运行。因为:这些操作系统并没有给这些程序提供“虚拟机”机制。

更详细的,看一些汇编/操作系统/处理器原理书籍。

#13


你还不知道MFC么?不可能吧?这就是microsoft foundation class的缩写,windows console application 是可以使用MFC的,在你建立project的时候,cpu默认的是保护模式(对于现在大部分的个人计算机来说),windows98应该是可以调用中断的,很多的dos下的游戏都使用了中断,这个应该是你程序编制的原因把。

#14


对于你的关于windows foudation class libarey,你还是自己找一本关于vc的书仔细看看把,这个是个很容易的问题

#15


To huangbeyond(校园人渣):

谢谢你的帮助,但我还是有些不明白:
1。按照你的说法,就是说VC6无法做16位的程序吧?而只能是32位“保护”模式?
2.16位的程序分“实”和“保护”,那32位的有“实”模式吗?
3。如果我先用MASM6.11编一个16位的ASM模块,能连到VC中的32位程序中吗?
4。VC中内嵌汇编(即用_asm{})就应该是32位的程序吧?


To zhakewei(天外有天):
你误会了,我怎么不知道MFC的大名呢:)我暑假才刚学完呢:)
我的意思是,应该不是MFC禁用的缘故,因为Win32控制台程序中默认中是“不用MFC库”的

#16


to:cywater2000(如果) 

1。VC6肯定是帮你把代码编译成“32位保护模式”的;
2。32位代码,只能是保护模式,没有实模式;
3。MASM6编译出的16位ASM模块,是不能被连接入32位的程序中的,因为代码指令长度与函数调用是完全不一样的。
4。对,VC内嵌的_asm{},就是32位的。

#17


“Win32 Console Application”下编程是不是实模式。
VC的所有程序都是32位的。
在Windows想调用DOS中断只能启动一个虚拟机,在虚拟机中运行16位程序,16位程序才能掉dos中断。

#18


To huangbeyond(校园人渣):

看来我把CPU与编译器搞混淆了

也就是说,286,386,...P3,P4都可以在“实”和“保护”模式下工作

那么,16位的“保护”模式是什么呢?
为什么386以上的CPU能在“实”模式下用到EAX,EBX等明显是32位的寄存器呢?
既然是32位的,为什么不是32位程序,也就是“保护模式”呢?

#19


16位保护模式,是一个很古老的技术了,它出现在286(286仍然是16位总线)时代;后来到了386(386是32位总线的CPU),就基本把这个技术淘汰了,但是,它确实存在过,但是时间非常短暂,以至于很多人都没有什么概念。

“286,386,...P3,P4都可以在“实”和“保护”模式下工作”,这样说法是正确的。

至于“386以上的CPU能在“实”模式下用到EAX,EBX等明显是32位的寄存器呢?”,那么,在那里有这样的代码呢?实模式只能出现在16位的时候,因为这是为了保证INTEL的CPU系列与其它操作系统的兼容性。说实话,我还真没有见过“实模式”代码访问EAX寄存器的。汇编代码段里的 ".386p"就已经保证是32位保护模式了,这样才能访问EAX,否则,你可以自己试试。:)

我再多说一些:
386,...P3,P4等CPU在系统启动之后,一律是工作在16位实模式;然后才被不同的操作系统执行“切换运行模式”的代码,才进入各种“保护模式”。当我们使用到VC6的时候,整个系统就是32位保护模式。
然而,Win9x操作系统,提供了一种手段--“虚拟机”,来保证兼容16位实模式的DOS程序,使之在运行的时候,感觉就像运行在真正的DOS环境里一样。

不知道我这样说,你是否有些明白了。
详细的,看《80X86汇编语言程序设计教程》,清华版,学习汇编的宝典。

#20


如果你的platform装了Dos6.22或更老的operating system,那你的vc的Console Application的AppWizard可以选择dos的platform,这样应该能够处理16位的保护模式吧。

#21


今天我去请教了我们的老师,再加上楼上各位的帮助,以及我查的一些资料,我算是明白了:

1)16位,32位的分法是按“寄存器”分的。用到哪种寄存器就是哪位程序
2)因为1)成立,所以16,32位程序都分“实”和“保护”模式
3)具体编程时,一般只考虑多少位程序,“实”还是“保护”那是系统考虑的


那现在我还有最后一个问题!

.386是什么意思?
.model flat是实模式吗?

如果是这们的话,也就是说:现在高级语言编程可以不用考虑“实”还是“保护”,但是“单独”编写汇编模块时,如果要写32位,保护模式的话,得“事先”声明吧?

多谢帮助!

#22


写错了,“.model flat是实模式吗?” => “.model flat是保护模式吗?”

#23


.386使你可以使用32位寄存器和非8086指令

#24


model  flat呢?

#25


最后一个问题都没有人帮吗?

#26


model  flat是指平坦内存模式

#27


平坦内存模式是保护模式吗?

#28


to:  huangbeyond(校园人渣) 
黄某某!!神仙啊,这么久才看到你?现在在那里爽啊?

#29


UP!

#30


平坦内存模式是保护模式吗?

如果不是,为什么“可以达到4G内存地址”呢?不是只有保护下才可以吗?

#31


UP!

#32


UP!

#33


(转载)

***************Title: Flat memory Model****************
***************  标题:平坦内存模型********************
*=================译自Tutor by Hutch==================*
*===Original:Collected and packed by dREAMtHEATER=====*
*======翻译:小桥 from QDU huasoft@163.com============*
*==================20020820 at home===================*
*******************************************************
之一:
平坦内存模型(Flat memory Model)


一个用本地32位Windows格式写成的程序是由所谓“平坦内存模型”创建的,它只有一个包含代码和数据的段。这个程序必须在386或更高的处理器上运行。

早期的16位代码,由段和偏移地址混合达到寻址64k(段的限制)。与此不同的是,平坦内存模型只需要偏移量却有4G的寻址范围。这使得汇编更容易书写,而代码总得来说也将快一点。

在这种平坦内存模型下,所有的段寄存器都被自动设为相同的值,而这意味着段/偏移寻址方式一定不能用于在32位Windows上运行的32位程序。

对于曾经在DOS下写程序的程序员来讲,一个32位的Windows PE可执行文件就像一个DOS下的COM文件,它们仅有一个包含程序代码和数据的段,而它们都直接用偏移地址,而不是段/偏移寻址方式。

平坦模型程序是近(NEAR)代码寻址以及近数据寻址,都是在4G的范围之内。

FS和GS段寄存器不在普通的程序中用到,但却被操作系统的某些程序实例所利用。
========================================================

#34


up

#35


多谢大家了

#1


我加到100分了,回答多少给多少分!

UP者有分!

#2


关注

#3


我正在试验,看来我想错了。

即使是VC6下的“Win32 Console Application”,默认也是32位的!!!

因为我无法调用DOS中断!

书上说应该禁止"Windows foundation class libraries”
可是怎么做呢?

我去看Project中的Setting了,有很多lib呀!
应该禁用哪些呢?

#4


1)书上说有些寄存器不用“保护”,比如AX(EAX),BX(EBX)等等。
  因为那本书用的是VC4.2,不知道现在VC6的规定有没有什么变化?

    VC6里边EAX,EBX也可以在汇编里直接用,其他寄存器最好先PUSH一下,用完了再POP

 2)关于“实”模式和“保护“模式编程的问题:
  16-bit Applications是不是就是“实”模式下的程序?
  而32-bit Applications是不是就是“保护”模式下的程序呢?
  或者说,只能用AX,BX的就是“实”的?
  能用EAX,EBX的就是“保护”的?

    不一定,windows下的DOS程序兼容用的是V86模式,并且实模式也可以用386指令和寄存器

3)
 为什么有一个"uses esi"呢?程序中还用到其他寄存器了呀?为什么没有提起?
另:.386表示是32位程序吗?也就是”保护模式”?
还有,那个“续行符”是什么意思?把下一行的“arraychar:ptr”提上去,而不用'\'可以吗?

   .386表示使用80386指令集,不一定是保护模式
   可以把下一行提上去而不用'\'

#5


在Win32里实模式与保护模式都是32位,Win32 Console Application 应该可以调用dos中断。

#6


。386表明使用的处理器,保护模式和实模式,protected mode and real mode,只是一种cpu的工作状态,保护模式可以提供一个4gb的可直接寻址的方式,每个程序都可以这样,而实模式并不能提供,关于这个方面的可以参考intel的处理器说明,mode flat,就表明使用的是保护模式了。
对于寄存器的使用,一般来说是没有限制的,ax,eax,都可以使用,只不过位数不一样而已。
console application 在winnt/2000下是没有办法调用中断的,这个是由于操作系统的原因,当然有些特殊的办法可以绕过去,还是用win98吧。
mfc的禁用在console下面都是禁用的,除非你选择使用才有可能。

#7


To wacky(笨笨狗):
不行的。
我试了,不能调用,不信,你可以试:

void main(void)
{
_asm
{
mov ah,8
int 21h
cmp al,'0'
jb big
cmp al,'9'
ja big
mov dx,ax
mov ah,2
int 21h
}
big: {;}
}

还有,按照你的说法,“16位”程序不一定就是“实”模式程序,
而“32”位程序不一定就是“保护”模式了?

那怎么控制是“实”的还是“保护”的呢?

#8


请说明,

要使用嵌入式汇编的目的,

如果要写Vxd建议你用专门的开发工具VToolsD,

要读写端口请进www.internals.com网站,下载WinIO库,

该库可以在Win9x/2000/xp下面屏蔽掉Windows的硬件保护机制,甚至于guest

登陆方式都可以直接访问硬件。

我认为只有要进行算法执行速度优化时,才应该考虑使用嵌入式汇编,

可以这样说,凡是使用嵌入式汇编实现的功能,使用正常“高级”方式都可

以实现。

#9


To zhakewei(天外有天):

我用的是win98,可还是不能调用DOS中断呀!

还有,应该不是“禁用MFC”,书上说是:“Windows foundation class libraries”

WFC?没听说过。

还有,mode flat表明是保护模式?那就是说,系统默认是“实”模式吧?

#10


To serverclient(郁闷)

谢谢你的建议。可是我现在是在“学习”,没有考虑其他因素。

我只是想搞懂而已。

希望你能帮助我

多谢

#11


UP

#12


to:cywater2000(如果) 


1。不要用VC来写“16位实模式汇编语言”
VC只能一个编辑界面,它能够正确运转,是依赖于它的link.exe等等文件的,说白了,VC什么都是不是,只是提供一个界面,来帮助程序员摆脱“命令行编译”的困境

2。在VC编辑环境下,C/CPP文件中使用了内嵌汇编代码,编译时,同样还是当作“32位保护模式”来编译的,因为VC缺省使用的编译器都是32位的!!!(这些文件在Microsoft Visual Studio\Common\MSDev98\Bin\下)所以,“Win32 Console Application”还是32位保护模式的,千万不要看见“黑底白字”就以为是DOS程序,就是16位实模式程序。

3。在阐述汇编语言时,“什么样的模式”和“16位还是32位”,是不能分开的!汇编语言有“16位实模式”“16位保护模式”“32位保护模式”几种,所以,仅仅是一个“16位汇编”,是不能说明任何问题的

4。综合你的情况,建议:直接使用汇编,MASM 6.1,或者TASM5,都可以,它们编译出来的就肯定是“16位实模式”,是肯定能调用“DOS中断”的。但是,要注意一点,WIN98下的运行的DOS程序,是“虚拟机”模式的。而16位实模式程序在NT/W2K下根本不能运行。因为:这些操作系统并没有给这些程序提供“虚拟机”机制。

更详细的,看一些汇编/操作系统/处理器原理书籍。

#13


你还不知道MFC么?不可能吧?这就是microsoft foundation class的缩写,windows console application 是可以使用MFC的,在你建立project的时候,cpu默认的是保护模式(对于现在大部分的个人计算机来说),windows98应该是可以调用中断的,很多的dos下的游戏都使用了中断,这个应该是你程序编制的原因把。

#14


对于你的关于windows foudation class libarey,你还是自己找一本关于vc的书仔细看看把,这个是个很容易的问题

#15


To huangbeyond(校园人渣):

谢谢你的帮助,但我还是有些不明白:
1。按照你的说法,就是说VC6无法做16位的程序吧?而只能是32位“保护”模式?
2.16位的程序分“实”和“保护”,那32位的有“实”模式吗?
3。如果我先用MASM6.11编一个16位的ASM模块,能连到VC中的32位程序中吗?
4。VC中内嵌汇编(即用_asm{})就应该是32位的程序吧?


To zhakewei(天外有天):
你误会了,我怎么不知道MFC的大名呢:)我暑假才刚学完呢:)
我的意思是,应该不是MFC禁用的缘故,因为Win32控制台程序中默认中是“不用MFC库”的

#16


to:cywater2000(如果) 

1。VC6肯定是帮你把代码编译成“32位保护模式”的;
2。32位代码,只能是保护模式,没有实模式;
3。MASM6编译出的16位ASM模块,是不能被连接入32位的程序中的,因为代码指令长度与函数调用是完全不一样的。
4。对,VC内嵌的_asm{},就是32位的。

#17


“Win32 Console Application”下编程是不是实模式。
VC的所有程序都是32位的。
在Windows想调用DOS中断只能启动一个虚拟机,在虚拟机中运行16位程序,16位程序才能掉dos中断。

#18


To huangbeyond(校园人渣):

看来我把CPU与编译器搞混淆了

也就是说,286,386,...P3,P4都可以在“实”和“保护”模式下工作

那么,16位的“保护”模式是什么呢?
为什么386以上的CPU能在“实”模式下用到EAX,EBX等明显是32位的寄存器呢?
既然是32位的,为什么不是32位程序,也就是“保护模式”呢?

#19


16位保护模式,是一个很古老的技术了,它出现在286(286仍然是16位总线)时代;后来到了386(386是32位总线的CPU),就基本把这个技术淘汰了,但是,它确实存在过,但是时间非常短暂,以至于很多人都没有什么概念。

“286,386,...P3,P4都可以在“实”和“保护”模式下工作”,这样说法是正确的。

至于“386以上的CPU能在“实”模式下用到EAX,EBX等明显是32位的寄存器呢?”,那么,在那里有这样的代码呢?实模式只能出现在16位的时候,因为这是为了保证INTEL的CPU系列与其它操作系统的兼容性。说实话,我还真没有见过“实模式”代码访问EAX寄存器的。汇编代码段里的 ".386p"就已经保证是32位保护模式了,这样才能访问EAX,否则,你可以自己试试。:)

我再多说一些:
386,...P3,P4等CPU在系统启动之后,一律是工作在16位实模式;然后才被不同的操作系统执行“切换运行模式”的代码,才进入各种“保护模式”。当我们使用到VC6的时候,整个系统就是32位保护模式。
然而,Win9x操作系统,提供了一种手段--“虚拟机”,来保证兼容16位实模式的DOS程序,使之在运行的时候,感觉就像运行在真正的DOS环境里一样。

不知道我这样说,你是否有些明白了。
详细的,看《80X86汇编语言程序设计教程》,清华版,学习汇编的宝典。

#20


如果你的platform装了Dos6.22或更老的operating system,那你的vc的Console Application的AppWizard可以选择dos的platform,这样应该能够处理16位的保护模式吧。

#21


今天我去请教了我们的老师,再加上楼上各位的帮助,以及我查的一些资料,我算是明白了:

1)16位,32位的分法是按“寄存器”分的。用到哪种寄存器就是哪位程序
2)因为1)成立,所以16,32位程序都分“实”和“保护”模式
3)具体编程时,一般只考虑多少位程序,“实”还是“保护”那是系统考虑的


那现在我还有最后一个问题!

.386是什么意思?
.model flat是实模式吗?

如果是这们的话,也就是说:现在高级语言编程可以不用考虑“实”还是“保护”,但是“单独”编写汇编模块时,如果要写32位,保护模式的话,得“事先”声明吧?

多谢帮助!

#22


写错了,“.model flat是实模式吗?” => “.model flat是保护模式吗?”

#23


.386使你可以使用32位寄存器和非8086指令

#24


model  flat呢?

#25


最后一个问题都没有人帮吗?

#26


model  flat是指平坦内存模式

#27


平坦内存模式是保护模式吗?

#28


to:  huangbeyond(校园人渣) 
黄某某!!神仙啊,这么久才看到你?现在在那里爽啊?

#29


UP!

#30


平坦内存模式是保护模式吗?

如果不是,为什么“可以达到4G内存地址”呢?不是只有保护下才可以吗?

#31


UP!

#32


UP!

#33


(转载)

***************Title: Flat memory Model****************
***************  标题:平坦内存模型********************
*=================译自Tutor by Hutch==================*
*===Original:Collected and packed by dREAMtHEATER=====*
*======翻译:小桥 from QDU huasoft@163.com============*
*==================20020820 at home===================*
*******************************************************
之一:
平坦内存模型(Flat memory Model)


一个用本地32位Windows格式写成的程序是由所谓“平坦内存模型”创建的,它只有一个包含代码和数据的段。这个程序必须在386或更高的处理器上运行。

早期的16位代码,由段和偏移地址混合达到寻址64k(段的限制)。与此不同的是,平坦内存模型只需要偏移量却有4G的寻址范围。这使得汇编更容易书写,而代码总得来说也将快一点。

在这种平坦内存模型下,所有的段寄存器都被自动设为相同的值,而这意味着段/偏移寻址方式一定不能用于在32位Windows上运行的32位程序。

对于曾经在DOS下写程序的程序员来讲,一个32位的Windows PE可执行文件就像一个DOS下的COM文件,它们仅有一个包含程序代码和数据的段,而它们都直接用偏移地址,而不是段/偏移寻址方式。

平坦模型程序是近(NEAR)代码寻址以及近数据寻址,都是在4G的范围之内。

FS和GS段寄存器不在普通的程序中用到,但却被操作系统的某些程序实例所利用。
========================================================

#34


up

#35


多谢大家了