免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: folklore
打印 上一主题 下一主题

如何用TSS进行任务切换?我切换不成功:((内有汇编代码/as86) [复制链接]

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
11 [报告]
发表于 2007-08-31 00:44 |只看该作者
十分感谢mik的帮助。问题找到了。
LDT为系统段,我把它设为数据段,结果不行了。
Intel手册中没说,我以为两个都行的都行的。
————————————————————————————————————————————
我的VM乱报错,以后我可不相信它了。结果让我绕了好大弯子,什么ss段出错,什么ds段不对。

我吐血。发了我好多精力啊。
--------------------------------------------------------------------------------------------------------
PS:看了intel的sample,我才明白什么才叫assembler。那叫什么乱七八糟的代码。是人看的么??又是cp,又是builer分配的。我手上没有masm,也没有dos,分析目标代码都不行。
附上:intel的代码

  1. 10.4.5 First Task
  2. The initialization procedure can run awhile in protected mode without
  3. initializing the task register; however, before the first task switch, the
  4. following conditions must prevail:
  5. ● There must be a valid task state segment (TSS) for the new task. The
  6. stack pointers in the TSS for privilege levels numerically less than or
  7. equal to the initial CPL must point to valid stack segments.
  8. ● The task register must point to an area in which to save the current
  9. task state. After the first task switch, the information dumped in this
  10. area is not needed, and the area can be used for other purposes.
  11. 10.5 Initialization Example
  12. $TITLE ('Initial Task')
  13. NAME INIT
  14. init_stack SEGMENT RW
  15. DW 20 DUP(?)
  16. tos LABEL WORD
  17. init_stack ENDS
  18. init_data SEGMENT RW PUBLIC
  19. DW 20 DUP(?)
  20. init_data ENDS
  21. init_code SEGMENT ER PUBLIC
  22. ASSUME DS:init_data
  23. nop
  24. nop
  25. nop
  26. init_start:
  27. ; set up stack
  28. mov ax, init_stack
  29. mov ss, ax
  30. mov esp, offset tos
  31. mov a1,1
  32. blink:
  33. xor a1,1
  34. out 0e4h,a1
  35. mov cx,3FFFh
  36. here:
  37. dec cx
  38. jnz here
  39. jmp SHORT blink
  40. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  41. Page 179 of 421
  42. hlt
  43. init_code ends
  44. END init_start, SS:init_stack, DS:init_data
  45. $TITLE('Protected Mode Transition -- 386 initialization')
  46. NAME RESET
  47. ;*****************************************************************
  48. ; Upon reset the 386 starts executing at address 0FFFFFFF0H. The
  49. ; upper 12 address bits remain high until a FAR call or jump is
  50. ; executed.
  51. ;
  52. ; Assume the following:
  53. ;
  54. ;
  55. ; - a short jump at address 0FFFFFFF0H (placed there by the
  56. ; system builder) causes execution to begin at START in segment
  57. ; RESET_CODE.
  58. ;
  59. ;
  60. ; - segment RESET_CODE is based at physical address 0FFFF0000H,
  61. ; i.e. at the start of the last 64K in the 4G address space.
  62. ; Note that this is the base of the CS register at reset. If
  63. ; you locate ROMcode above this address, you will need to
  64. ; figure out an adjustment factor to address things within this
  65. ; segment.
  66. ;
  67. ;*****************************************************************
  68. $EJECT ;
  69. ; Define addresses to locate GDT and IDT in RAM.
  70. ; These addresses are also used in the BLD386 file that defines
  71. ; the GDT and IDT. If you change these addresses, make sure you
  72. ; change the base addresses specified in the build file.
  73. GDTbase EQU 00001000H ; physical address for GDT base
  74. IDTbase EQU 00000400H ; physical address for IDT base
  75. PUBLIC GDT_EPROM
  76. PUBLIC IDT_EPROM
  77. PUBLIC START
  78. DUMMY segment rw ; ONLY for ASM386 main module stack init
  79. DW 0
  80. DUMMY ends
  81. ;*****************************************************************
  82. ;
  83. ; Note: RESET CODE must be USEl6 because the 386 initally executes
  84. ; in real mode.
  85. ;
  86. RESET_CODE segment er PUBLIC USE16
  87. ASSUME DS:nothing, ES:nothing
  88. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  89. Page 180 of 421
  90. ;
  91. ; 386 Descriptor template
  92. DESC STRUC
  93. lim_0_15 DW 0 ; limit bits (0..15)
  94. bas_0_15 DW 0 ; base bits (0..15)
  95. bas_16_23 DB 0 ; base bits (16..23)
  96. access DB 0 ; access byte
  97. gran DB 0 ; granularity byte
  98. bas_24_31 DB 0 ; base bits (24..31)
  99. DESC ENDS
  100. ; The following is the layout of the real GDT created by BLD386.
  101. ; It is located in EPROM and will be copied to RAM.
  102. ;
  103. ; GDT[O] ... NULL
  104. ; GDT[1] ... Alias for RAM GDT
  105. ; GDT[2] ... Alias for RAM IDT
  106. ; GDT[2] ... initial task TSS
  107. ; GDT[3] ... initial task TSS alias
  108. ; GDT[4] ... initial task LDT
  109. ; GDT[5] ... initial task LDT alias
  110. ;
  111. ; define entries in GDT and IDT.
  112. GDT_ENTRIES EQU 8
  113. IDT_ENTRIES EQU 32
  114. ; define some constants to index into the real GDT
  115. GDT_ALIAS EQU 1*SIZE DESC
  116. IDT_ALIAS EQU 2*SIZE DESC
  117. INIT_TSS EQU 3*SIZE DESC
  118. INIT_TSS_A EQU 4*SIZE DESC
  119. INIT_LDT EQU 5*SIZE DESC
  120. INIT_LDT_A EQU 6*SIZE DESC
  121. ;
  122. ; location of alias in INIT_LDT
  123. INIT_LDT_ALIAS EQU 1*SIZE DESC
  124. ;
  125. ; access rights byte for DATA and TSS descriptors
  126. DS_ACCESS EQU 010010010B
  127. TSS_ACCESS EQU 010001001B
  128. ;
  129. ; This temporary GDT will be used to set up the real GDT in RAM.
  130. Temp_GDT LABEL BYTE ; tag for begin of scratch GDT
  131. NULL_DES DESC <> ; NULL descriptor
  132. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  133. Page 181 of 421
  134. ; 32-Gigabyte data segment based at 0
  135. FLAT_DES DESC <0FFFFH,0,0,92h,0CFh,0>
  136. GDT_eprom DP ? ; Builder places GDT address and limit
  137. ; in this 6 byte area.
  138. IDT_eprom DP ? ; Builder places IDT address and limit
  139. ; in this 6 byte area.
  140. ;
  141. ; Prepare operand for loadings GDTR and LDTR.
  142. TGDT_pword LABEL PWORD ; for temp GDT
  143. DW end_Temp_GDT_Temp_GDT -1
  144. DD 0
  145. GDT_pword LABEL PWORD ; for GDT in RAM
  146. DW GDT_ENTRIES * SIZE DESC -1
  147. DD GDTbase
  148. IDT_pword LABEL PWORD ; for IDT in RAM
  149. DW IDT_ENTRIES * SIZE DESC -1
  150. DD IDTbase
  151. end_Temp_GDT LABEL BYTE
  152. ;
  153. ; Define equates for addressing convenience.
  154. GDT_DES_FLAT EQU DS:GDT_ALIAS +GDTbase
  155. IDT_DES_FLAT EQU DS:IDT_ALIAS +GDTbase
  156. INIT_TSS_A_OFFSET EQU DS:INIT_TSS_A
  157. INIT_TSS_OFFSET EQU DS:INIT_TSS
  158. INIT_LDT_A_OFFSET EQU DS:INIT_LDT_A
  159. INIT_LDT_OFFSET EQU DS:INIT_LDT
  160. ; define pointer for first task switch
  161. ENTRY POINTER LABEL DWORD
  162. DW 0, INIT_TSS
  163. ;******************************************************************
  164. ;
  165. ; Jump from reset vector to here.
  166. START:
  167. CLI ;disable interrupts
  168. CLD ;clear direction flag
  169. LIDT NULL_des ;force shutdown on errors
  170. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  171. Page 182 of 421
  172. ;
  173. ; move scratch GDT to RAM at physical 0
  174. XOR DI,DI
  175. MOV ES,DI ;point ES:DI to physical location 0
  176. MOV SI,OFFSET Temp_GDT
  177. MOV CX,end_Temp_GDT-Temp_GDT ;set byte count
  178. INC CX
  179. ;
  180. ; move table
  181. REP MOVS BYTE PTR ES:[DI],BYTE PTR CS:[SI]
  182. LGDT tGDT_pword ;load GDTR for Temp. GDT
  183. ;(located at 0)
  184. ; switch to protected mode
  185. MOV EAX,CR0 ;get current CRO
  186. MOV EAX,1 ;set PE bit
  187. MOV CRO,EAX ;begin protected mode
  188. ;
  189. ; clear prefetch queue
  190. JMP SHORT flush
  191. flush:
  192. ; set DS,ES,SS to address flat linear space (0 ... 4GB)
  193. MOV BX,FLAT_DES-Temp_GDT
  194. MOV US,BX
  195. MOV ES,BX
  196. MOV SS,BX
  197. ;
  198. ; initialize stack pointer to some (arbitrary) RAM location
  199. MOV ESP, OFFSET end_Temp_GDT
  200. ;
  201. ; copy eprom GDT to RAM
  202. MOV ESI,DWORD PTR GDT_eprom +2 ; get base of eprom GDT
  203. ; (put here by builder).
  204. MOV EDI,GDTbase ; point ES:EDI to GDT base in RAM.
  205. MOV CX,WORD PTR gdt_eprom +0 ; limit of eprom GDT
  206. INC CX
  207. SHR CX,1 ; easier to move words
  208. CLD
  209. REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
  210. ;
  211. ; copy eprom IDT to RAM
  212. ;
  213. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  214. Page 183 of 421
  215. MOV ESI,DWORD PTR IDT_eprom +2 ; get base of eprom IDT
  216. ; (put here by builder)
  217. MOV EDI,IDTbase ; point ES:EDI to IDT base in RAM.
  218. MOV CX,WORD PTR idt_eprom +0 ; limit of eprom IDT
  219. INC CX
  220. SHR CX,1
  221. CLD
  222. REP MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
  223. ; switch to RAM GDT and IDT
  224. ;
  225. LIDT IDT_pword
  226. LGDT GDT_pword
  227. ;
  228. MOV BX,GDT_ALIAS ; point DS to GDT alias
  229. MOV DS,BX
  230. ;
  231. ; copy eprom TSS to RAM
  232. ;
  233. MOV BX,INIT_TSS_A ; INIT TSS A descriptor base
  234. ; has RAM location of INIT TSS.
  235. MOV ES,BX ; ES points to TSS in RAM
  236. MOV BX,INIT_TSS ; get inital task selector
  237. LAR DX,BX ; save access byte
  238. MOV [BX].access,DS_ACCESS ; set access as data segment
  239. MOV FS,BX ; FS points to eprom TSS
  240. XOR si,si ; FS:si points to eprom TSS
  241. XOR di,di ; ES:di points to RAM TSS
  242. MOV CX,[BX].lim_0_15 ; get count to move
  243. INC CX
  244. ;
  245. ; move INIT_TSS to RAM.
  246. REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
  247. MOV [BX].access,DH ; restore access byte
  248. ;
  249. ; change base of INIT TSS descriptor to point to RAM.
  250. MOV AX,INIT_TSS_A_OFFSET.bas_0_15
  251. MOV INIT_TSS_OFFSET.bas_0_15,AX
  252. MOV AL,INIT_TSS_A_OFFSET.bas_16_23
  253. MOV INIT_TSS_OFFSET.bas_16_23,AL
  254. MOV AL,INIT_TSS_A_OFFSET.bas_24_31
  255. MOV INIT_TSS_OFFSET.bas_24_31,AL
  256. ;
  257. ; change INIT TSS A to form a save area for TSS on first task
  258. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  259. Page 184 of 421
  260. ; switch. Use RAM at location 0.
  261. MOV BX,INIT_TSS_A
  262. MOV WORD PTR [BX].bas_0_15,0
  263. MOV [BX].bas_16_23,0
  264. MOV [BX].bas_24_31,0
  265. MOV [BX].access,TSS_ACCESS
  266. MOV [BX].gran,O
  267. LTR BX ; defines save area for TSS
  268. ;
  269. ; copy eprom LDT to RAM
  270. MOV BX,INIT_LDT_A ; INIT_LDT_A descriptor has
  271. ; base address in RAM for INIT_LDT.
  272. MOV ES,BX ; ES points LDT location in RAM.
  273. MOV AH,[BX].bas_24_31
  274. MOV AL,[BX].bas_16_23
  275. SHL EAX,16
  276. MOV AX,[BX].bas_0_15 ; save INIT_LDT base (ram) in EAX
  277. MOV BX,INIT_LDT ; get inital LDT selector
  278. LAR DX,BX ; save access rights
  279. MOV [BX].access,DS_ACCESS ; set access as data segment
  280. MOV FS,BX ; FS points to eprom LDT
  281. XOR si,si ; FS:SI points to eprom LDT
  282. XOR di,di ; ES:DI points to RAM LDT
  283. MOV CX,[BX].lim_0_15 ; get count to move
  284. INC CX
  285. ;
  286. ; move initial LDT to RAM
  287. REP MOVS BYTE PTR ES:[di],BYTE PTR FS:[si]
  288. MOV [BX].access,DH ; restore access rights in
  289. ; INIT_LDT descriptor
  290. ;
  291. ; change base of alias (of INIT_LDT) to point to location in RAM.
  292. MOV ES:[INIT_LDT_ALIAS].bas_0_15,AX
  293. SHR EAX,16
  294. MOV ES:[INIT_LDT_ALIAS].bas_16_23,AL
  295. MOV ES:[INIT_LDT_ALIAS].bas_24_31,AH
  296. ;
  297. ; now set the base value in INIT_LDT descriptor
  298. MOV AX,INIT_LDT_A_OFFSET.bas_0_15
  299. MOV INIT_LDT_OFFSET.bas_0_15,AX
  300. MOV AL,INIT_LDT_A_OFFSET.bas_16_23
  301. MOV INIT_LDT_OFFSET.bas_16_23,AL
  302. MOV AL,INIT_LDT_A_OFFSET.bas_24_31
  303. INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  304. Page 185 of 421
  305. MOV INIT_LDT_OFFSET.bas_24_31,AL
  306. ;
  307. ; Now GDT, IDT, initial TSS and initial LDT are all set up.
  308. ;
  309. ; Start the first task!
  310. '
  311. JMP ENTRY_POINTER
  312. RESET_CODE ends
  313. END START, SS:DUMMY,DS:DUMMY
复制代码

论坛徽章:
0
12 [报告]
发表于 2007-08-31 19:04 |只看该作者
原帖由 folklore 于 2007-8-31 00:44 发表
十分感谢mik的帮助。问题找到了。
LDT为系统段,我把它设为数据段,结果不行了。
Intel手册中没说,我以为两个都行的都行的。
————————————————————————————————————— ...


没仔细看你的代码,想练习 TSS, 不需要定义 LDT 呀。

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
13 [报告]
发表于 2007-08-31 23:32 |只看该作者
原帖由 mik 于 2007-8-31 19:04 发表


没仔细看你的代码,想练习 TSS, 不需要定义 LDT 呀。


能说详细点么?那应如何设定啊?


不定义LDT,TSS的LDT指向什么地方?
就算指向GDT,也是要在GDT中有个表项的吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP