|
保护模式编程起步问题求助
INCLUDE 386SCD.INC ;---------------------------------------------------------------------------- DSEG SEGMENT USE16 ;16位数据段 ;---------------------------------------------------------------------------- GDT LABEL BYTE ;全局描述符表 DUMMY Desc <> ;空描述符 Normal Desc <0ffffh,,,ATDW,,> ;规范段描述符 Code32 Desc <0,,,ATCE,D32,> ;32位代码段描述符 Code16 Desc <0ffffh,,,ATCE,,> ;16位代码段描述符 DataS Desc <DataLen-1,0,10h,ATDR,,> ;源数据段描述符 DataD Desc <3999,8000h,0bh,ATDW,,> ;显示缓冲区描述符 Stacks Desc <StackLen-1,,,ATDW,,> ;堆栈段描述符 ;---------------------------------------------------------------------------- GDTLen = $-GDT ;全局描述符表长度 VGDTR PDesc <GDTLen-1,> ;伪描述符 ;---------------------------------------------------------------------------- SaveSP DW ? ;用于保存SP寄存器 SaveSS DW ? ;用于保存SS寄存器 ;---------------------------------------------------------------------------- Normal_Sel = Normal-GDT ;规范段描述符选择子 Code32_Sel = Code32-GDT ;32位代码段选择子 Code16_Sel = Code16-GDT ;16位代码段选择子 DataS_Sel = Datas-GDT ;源数据段选择子 DataD_Sel = DataD-GDT ;目标数据段选择子 Stacks_Sel = Stacks-GDT ;堆栈段描述符选择子 ;---------------------------------------------------------------------------- DataLen = 16 ;---------------------------------------------------------------------------- DSEG ENDS ;数据段定义结束 ;---------------------------------------------------------------------------- StackSeg SEGMENT PARA STACK USE16 StackLen = 256 DB StackLen DUP(0) StackSeg ENDS ;---------------------------------------------------------------------------- CSEG1 SEGMENT USE16 'REAL' ;16位代码段 ASSUME CS:CSEG1,DS:DSEG ;---------------------------------------------------------------------------- Start PROC mov ax,DSEG mov ds,ax push bx mov ebx,C32Len mov code32.limitl,bx pop bx ;准备要加载到GDTR的伪描述符 mov bx,16 mul bx add ax,OFFSET GDT ;计算并设置基地址 adc dx,0 ;界限已在定义时设置好 mov WORD PTR VGDTR.Base,ax mov WORD PTR VGDTR.Base+2,dx ;设置32位代码段描述符 mov ax,CSEG2 mul bx mov WORD PTR Code32.BaseL,ax mov BYTE PTR Code32.BaseM,dl mov BYTE PTR Code32.BaseH,dh ;设置16位代码段描述符 mov ax,CSEG3 mul bx mov WORD PTR Code16.BaseL,ax ;代码段开始偏移为0 mov BYTE PTR Code16.BaseM,dl ;代码段界限已在定义时设置好 mov BYTE PTR Code16.BaseH,dh ;设置堆栈段描述符 mov ax,ss mov WORD PTR SaveSS,ax mov WORD PTR SaveSP,sp mov ax,StackSeg mul bx mov WORD PTR Stacks.BaseL,ax mov BYTE PTR Stacks.BaseM,dl mov BYTE PTR Stacks.BaseH,dh ;加载GDTR lgdt VGDTR;QWORD PTR VGDTR cli ;关中断 EnableA20 ;打开地址线A20 ;切换到保护方式 mov eax,cr0 or al,1 mov cr0,eax ;清指令预取队列,并真正进入保护方式 JUMP16 Code32_Sel,<OFFSET SPM32> ToReal: ;现在又回到实方式 mov ax,DSEG mov ds,ax mov sp,SaveSP mov ss,SaveSS DisableA20 sti mov ax,4c00h int 21h Start ENDP ;---------------------------------------------------------------------------- CSEG1 ENDS ;代码段定义结束 ;---------------------------------------------------------------------------- CSEG2 SEGMENT USE32 'PM32' ASSUME CS:CSEG2 ;---------------------------------------------------------------------------- SPM32 PROC mov ax,Stacks_Sel mov ss,ax mov esp,StackLen mov ax,DataS_Sel mov ds,ax mov ax,DataD_Sel mov es,ax xor esi,esi xor edi,edi mov ecx,DataLen cld Next: lodsb push ax CALL ToASCII mov ah,7 shl eax,16 pop ax shr al,4 CALL ToASCII mov ah,7 stosd mov al,20h stosw loop Next JUMP32 Code16_Sel,<OFFSET SPM16> SPM32 ENDP ;---------------------------------------------------------------------------- ToASCII PROC and al,00001111b add al,30h cmp al,39h jbe Isdig add al,7 IsDig: ret ToASCII ENDP ;---------------------------------------------------------------------------- C32Len = $ ;---------------------------------------------------------------------------- CSEG2 ENDS ;---------------------------------------------------------------------------- CSEG3 SEGMENT USE16 'PM16' ASSUME CS:CSEG3 ;---------------------------------------------------------------------------- SPM16 PROC xor si,si mov di,DataLen*3*2 mov ah,7 mov cx,DataLen AGain: lodsb stosw loop AGain mov ax,Normal_sel mov ds,ax mov es,ax mov ss,ax mov eax,cr0 and al,11111110b mov cr0,eax jmp FAR PTR ToReal SPM16 ENDP ;---------------------------------------------------------------------------- CSEG3 ENDS ;---------------------------------------------------------------------------- END Start 这样的教程还真是让人头疼 |
|
求助一段代码看不懂,主要用途
经过你的开导,我暂时放弃了在WINDOWS系统下修改GDT的打算。 http://bbs.pediy.com/showthread.php?t=170683去这里解答我的问题吧,有分给的,50KX扔了也可惜。 |
|
一道算法题,求解。
边续存储线性表的实现,我只想到了一种方法,好像有点作弊。 先用汇编伪描述下。 _result equ this word;结果数组与原数存指向同一地址 _source dd 2*n dup(0);用来存放长度为2N的数组,键盘接收 xor di,di mov cx,n a: mov word ptr [_result+di+2],[_result+di+n*4] add di,4 loop a 用C的话,若是TC long f[2n]={……}; int *p=(int*)f; int *q=(int*)f(n); for (int i=0,i<n,i++) { (&(p+1))=(&q); p+=2; q+=2; } 那么INT f[]就是所求的数组。 太晚了,实属梦游。应该是*(P+1)=*(p+2n) |
|
求助一段代码看不懂,主要用途
我是来求答案的,刚开始学习保护模式编程,所以很多东西都不懂,见凉。内存的分页管理我还没有学到。 我所指的是,代码段描述符中段属性的TYPE字段,其值只能是8-F。如果是8或9的话,在保护模式下,CPU不允许通过CS:[R32]来访问这段内存,无论是读还是写。在GDT中,是通过增加一个描述符也指向这一个地址,但新增加的描述符TYPE字段的值是一般是零到3,如果是2或3的话则表示这是一个向上扩展可读写的数据段。我们将这一个新增描述符的索引送入段选择子比如:DS,则可通过DS:[R32]来访问这段内存,而且CPU是把这段内存当作数据段来访问的。但LDT部分我还没学到,我只是见LDT与GDT的描述符格式是一样的,所以猜想,LDT中也是如此,不知道对不对?WIN32中,应用程序使用的内存地址空间一部分在GDT中,一部分在LDT中。应用程序的代码段描述符肯定在LDT中。其实,我想问的就是:LDT是由我们程序自己还是由操作系统创建的,应用程序中能不能对LDT进行修改;还有就是,让CPU写代码段的三种方法,其最终是通过什么来实现的,由谁来实现——编译链接器,还是操作系统。还有就是权限,到这里我想到,应用程序都是三级的,那么LDT应该是由操作系统来实现的。那么继续猜,系统是创建LDT时已经为代码段描述符创建了别名描述符,但其属性默认是不可写的,而我们对代码段的访问其实是通过这个描述符来访问的。要实面对代码段的写操作,就要更改PE头部的一些内容,使操作系统加载程序时创建的别名描述符是可写的。不知道猜得对不对,请指点。 |
|
保护模式编程起步问题求助
用bochs,是不是要在虚拟盘上模拟DOS? |
|
保护模式编程起步问题求助
程序1在实DOS下程序可执行,但调试还是没有办法。另外,程序2的编译…… |
|
一道算法题,求解。
没正经学过计算机,不太懂题目的要求。 不过,如果是在实际中解决问题的话,我会这样想:算法应该以数据结构为基础。连续存储的一维数组,显然在排序上并没有什么优势,但如果使用链式存储,那解决起来就轻松多了。 |
|
求助一段代码看不懂,主要用途
原来以为:保护模式下代码段都是不可写的,要写的话只能使用别名。就是在描述符表中加入一个新的描述符,指向代码段,但其属性是可写的数据段。用这个新的描述符就可以访问代码段,而不管代码段的属性是什么,哪怕是不可读的。 那么楼上所提到到的方法是不是最终也是通过这种方法实现的?但由谁来实现,操作系统还是应用程序,还是两者都可以? 不好意思,我问的问题没分给的 |
|
保护模式编程起步问题求助
CMD下无法执行。其实,执行不了也猜到了,具体原因却不太清楚。 程序就死在 lgdt VGDTR这一行。如果这一句成功了,那么,全局描述符表就要换成应用程序里设置的了,整个WINDOWS是不是要死掉。WINDOWS不想死,所以不让程序这么做? 怎么做到的?是因为程序的权限被设为三级?三级之下不能加载GDTR?进而程序也不能把自己的权限提升到0级。那么那句.386P在编译时又做了些什么呢? OF01662000在纯DOS下能否执行呢?为什么? |
|
分析C盘引导扇区,不解
首先,STI是开中断。 0:700后的数据,应该是指令。发现当指令中使用32位寄存器时,用DOS的DEBUG或DEBUG中的U命令看时,会出现花指令的情况。 用U命令查看C盘引导目录的内容,分析无法启动的原因,可能是7C00后面的一些数据被系统中的其他程序覆盖。 等了这么长时间,没有答案,似乎可以结帖了 |
|
分析C盘引导扇区,不解
不同的硬盘接口的两台机子,其代码稍有区别,不知区别是否是因为接口的不同。 把这段代码放在DOS下执行,则会死机,用DEBUG逐条执行,发现,死机会发生在执行repz movsb 或repz movsw时,当覆盖0:704—0:705内存单元内容时,光标照常闪烁,键盘无反映。怀疑重要数据被修改导致死机。这怀疑是不是真的?如果是,那么这段数据是什么?这段数据基本看不懂,当作数据来看吧:有意义的ASIC码并不多;当作指令则多是花指令;键盘缓存区,也不像,当然也可能是我没看懂。再说若是BIOS程序用到的内存,那么系统就应该彻底无法启动。所以,这应该是DOS系统用到的内存,是用来放什么的? |
|
如何让电脑无法启动
貌似软件方法不可靠。安装盘什么的好像都能让电脑启动。 硬件方法有点白。 有一个折中的办法,修改ROM的程序。先得看ROM的类型。EEPROM,EPROM这比较好搞。无论是接电还是爆晒,效果应该不错,开不了机。PROM就麻烦点了,虽然也可以加电的方法来解决,但估计12V应该不够,具体多大能使计算机开不了机,又嗅不到焦糊味,没试过,更重要的是一旦改了就不好恢复。最麻烦的还是ROM,二极管这东西不太懂,加多大电能行不知道,不过把ROM的壳给剥开,应该能有办法,当然也有一个无法恢复的缺点。 |
|
汉化VB程序时遇到的问题
顶起来,没人看了 |
|
汉化VB程序时遇到的问题
感谢楼上的建议。我试着把ENGLISH.lng里面的部分英文改为中文:“&PRINT”改为“&PR打T”那么程序在运行时会显示为:“(下划线P)R”后面的所有内容都不显示。 一般程序如果无法显示中文的话会出乱码,可是这个程序连乱码都没有,不知道为什么。 是不是程序在获取这些字符时进行了检查,对ASCII值做了规定。 是不要反汇编跟踪?可惜OD还不怎么会用。怎么能找到程序设定字符检查的地方? 我想请教此种情况的可能原因,和基本的解决方法。(不存在侵权问题,程序作者在说明文件中对程序的多语言支持表示欢迎)。 |
|
汉化VB程序时遇到的问题
不能再创零回复记录了,先自己占个位吧 |
|
[求助]概念性问题,PE文件在内存中的存在方式?
请教:4GB没有被加载的部分是存在硬盘上吗?是指虚拟内存吗? |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值