您的位置:首页 > 其它

系统的简单注解 - 7 04_process.asm文件

2017-04-21 11:35 369 查看


该文件包括了系统进程的创建、用户进程的安装、进程控制块链表的控制(运行链表、休眠链表)、进程窗口的绘制、硬盘扇区的读取。

 

Set_TSS_sel:安装TSS段;

Set_LDT_sel:安装LDT段;

Load_core_task:创建系统进程(权限0);

Load_usr_task:创建用户进程(权限3);

mount_task_running_que:将进程结构安装到运行队列中;

mount_task_run_to_pend_que:将进程结构从运行队列放入暂停队列;

mount_task_pend_to_run_que:将进程结构从暂停队列放入运行队列;

switch_task2:轮转切换当前执行的进程;

wakeup_task:检查进程休眠时间是否到时,并唤醒;

draw_task_window:绘制用户进程窗口;

read_hard_disk_0:从硬盘读取一个逻辑扇区;

 
代码中的SYS_PROC、USR1_PROC、USR2_PROC分别保存了系统进程、用户进程1、用户进程2的控制块。

;===============================================================================

;=== 本程序包括了进程管理的主要功能:                                        ===

;=== 1.进程结构初始化                                                        ===

;=== 2.进程的安装、启动、唤醒、睡眠                                          ===

;===============================================================================

;-------------------------------------------------------------------------------

Set_TSS_sel:                              ;安装TSS段

                                          ;输入参数: eax-—TSS段基地址

                                          ;输出参数: cx—-gdt中的选择子

 

     push edx                              ;保存edx

     xor ecx, ecx                          ;ecx清零

     sgdt [pgdt]                           ;获取gdt表长度和基址

     mov cx, word [pgdt]                   ;段界限

     mov edx, dword [pgdt+2]               ;段基址

     inc cx                                ;gdt表长度

     add edx, ecx                          ;安装地址       

     mov word [edx], 103                   ;TSS段长度的低16位

     mov word [edx+2], ax                  ;TSS段基址的低16位

     shr eax, 16                           ;TSS段基址右移16位

     mov byte [edx+4], al                  ;TSS段基址的中8位

     mov byte [edx+7], ah                  ;TSS段基址的高8位

     mov byte [edx+5], 1_00_0_1001B        ;P-1,TYPE-9(可用386TSS段)

     mov byte [edx+6], 0_1_0_0_0000B       ;G-0,X-1,limit-0

     add word [pgdt], 8                    ;gdt表长度增加8字节

     lgdt [pgdt]                           ;重新安装gdt表到系统

     pop edx                               ;弹出edx

  ret

;-------------------------------------------------------------------------------

Set_LDT_sel:                               ;安装LDT段

                                           ;输入参数: eax-—LDT段基地址

                                           ;输出参数: cx—-gdt中的选择子

 

     push edx                              ;保存edx

     xor ecx, ecx                          ;ecx清零

     sgdt [pgdt]                           ;获取gdt表长度和基址

     mov cx, word [pgdt]                   ;段界限

     mov edx, dword [pgdt+2]               ;段基址

     inc cx                                ;gdt表长度

     add edx, ecx                          ;安装地址       

     mov word [edx], 15                    ;LDT段长度的低16位

     mov word [edx+2], ax                  ;LDT段基址的低16位

     shr eax, 16                           ;LDT段基址右移16位

     mov byte [edx+4], al                  ;LDT段基址的中8位

     mov byte [edx+7], ah                  ;LDT段基址的高8位

     mov byte [edx+5], 1_11_0_0010B        ;P-1,DPL=3,TYPE-2(LDT段)

     mov byte [edx+6], 0_1_0_0_0000B       ;G-0,X-1,limit-0

     add word [pgdt], 8                    ;gdt表长度增加8字节

     lgdt [pgdt]                           ;重新安装gdt表到系统

     pop edx                               ;弹出edx

     ret

;-------------------------------------------------------------------------------

Load_core_task:                           ;创建系统进程(权限0)

 

     pushad

 

     ;内核任务的TSS段填写,清空缓冲区,使段内所有保留位置0

     mov eax, SYS_PROC + proc_ctrl.tss

     mov ecx, 104

_init_tss:

     mov byte [eax], 0x0

     inc eax

     loop _init_tss

 

     mov eax, SYS_PROC + proc_ctrl.tss

     mov ecx, cr3

     mov dword [eax + 0x1c], ecx        ;此处的CR3的写入必须要有,因为Set_TSS_sel不会主动加入页目录!!!

 

     ;在gdt中写入tss段描述符

     call Set_TSS_sel                   ;安装TSS,段首地址在eax中

     mov [SYS_PROC + proc_ctrl.task_sel], cx

     ltr cx                             ;将内核任务写入系统

 

     mov eax, SYS_PROC

     mov [SYS_PROC + proc_ctrl.pre_task], eax   ;系统进程的前一进程指向自己

     mov [SYS_PROC + proc_ctrl.next_task], eax ;系统进程的后一进程也指向自己

 

     ;记录当前工作进程

     mov eax, SYS_PROC

     mov [_task_now], eax               ;当前工作进程为系统进程

     add eax, proc_ctrl.next_task

     mov dword [eax], SYS_PROC          ;系统进程控制结构的下一个进程地址 指向自己

     mov eax, SYS_PROC

     add eax, proc_ctrl.state

     mov word [eax], task_running     ;工作进程状态为 正在运行

     popad

 

     ret

 

;-------------------------------------------------------------------------------

Load_usr_task:                            ;创建用户进程(权限3)

                                          ;输入参数: eax--用户进程的起始扇区号

            ;输入参数: ebx--用户进程扇区个数

            ;输入参数: ecx--进程PROC_CTRL结构的偏移地址

                                          ;输出参数: cx—-用户进程TSS段在gdt中的选择子         

     push eax                             ;[ebp + 24] 起始扇区号

     push ebx                           ;[ebp + 20] 扇区个数

     push ecx                             ;[ebp + 16] 进程控制结构proc_ctrl的偏移

     ;用户内存区分配用户“页目录”、“页表1”、“app页”、“用户堆栈esp3”三页

     call Alloc_usr_page

     push eax                           ;[ebp + 12] 页目录页

     call Alloc_usr_page

     push eax                             ;[ebp + 8] 页表1

     call Alloc_usr_page

     push eax                             ;[ebp + 4] app页

     call Alloc_usr_page

     push eax                             ;[ebp] 用户堆栈

     mov ebp, esp

 

     ;将用户页目录、页表1、app页映射到系统进程的前三页

     mov eax, [ebp + 12]

     or eax, 0x7

     mov dword [0xffc00000], eax

     mov eax, [ebp + 8]

     or eax, 0x7

     mov dword [0xffc00004], eax

     mov eax, [ebp + 4]

     or eax, 0x7

     mov dword [0xffc00008], eax

 

     ;拷贝系统页目录到用户页目录

     mov ecx, 1024

     xor edx, edx

_dir_cpy:

     mov eax, dword [0xfffff000 + edx]

     mov dword [edx], eax

     add edx, 4

     loop _dir_cpy

     ;用户页目录最后一项指向自己

     mov eax, [ebp + 12]

     or eax, 0x7

     mov dword [4092], eax

     ;用户页目录第一项指向页表1

     mov eax, [ebp + 8]

     or eax, 0x7

     mov dword [0], eax

     ;用户页表1第一项指向用户app页(对应线性地址:0x0-0x1000)

     mov eax, [ebp + 4]

     or eax, 0x7

     mov dword [0x1000], eax

     ;用户页表1第二项指向权限3堆栈(对应线性地址:0x1000-0x2000)

     mov eax, [ebp]

     or eax, 0x7

     mov dword [0x1004], eax

     ;将用户进程数据从逻辑扇区拷贝到到用户app页中

     mov eax, [ebp + 24]

     mov ebx, 0x2000

     mov ecx, [ebp + 20]

_cpy_disk:

     call read_hard_disk_0

     inc eax

     loop _cpy_disk

 

     ;将调用门信息写入用户进程

     mov ax, word [far_caller_1 + 4]

     mov [0x2004], ax

     mov ax, word [far_caller_2 + 4]

     mov [0x200a], ax

     mov ax, word [far_caller_3 + 4]

     mov [0x2010], ax

     mov ax, word [far_caller_4 + 4]

     mov [0x2016], ax

     mov ax, word [far_caller_5 + 4]

     mov [0x201c], ax

 

     ;初始化用户ldt段(代码段、数据段)

     mov eax, [ebp + 16]

     add eax, proc_ctrl.ldt

     mov dword [eax], ldt_code_low_dd

     mov dword [eax + 4], ldt_code_high_dd

     mov dword [eax + 8], ldt_data_low_dd

     mov dword [eax + 0x0c], ldt_data_high_dd

 

     ;将用户ldt段加入gdt

     call Set_LDT_sel

     mov eax, [ebp + 16]

     add eax, proc_ctrl.ldt_sel

     mov [eax], cx

     ;初始化用户进程TSS页,段内所有保留位都清空

     mov eax, [ebp + 16]

     add eax, proc_ctrl.tss

     push eax

     mov ecx, 26

     xor edx, edx

_init_usr_tss:

     mov dword [eax + edx], 0x0

     add edx, 4

     loop _init_usr_tss

 

     ;逐项填写TSS段

     call Alloc_sys_page                       ;分配用户进程使用的R0权限下的堆栈页

     mov edx, eax

     add edx, 4092                             ;esp0指针指向页的最后

     pop eax                                   ;恢复指向tss段的首地址

     mov dword [eax+0x4], edx                  ;esp0

     mov word [eax+0x8], flat_mode_data        ;ss0

     mov ebx, [ebp + 12]

     mov dword [eax+0x1c], ebx                 ;cr3

     mov dword [eax+0x20], 48                  ;eip

     pushfd

     pop ebx

     mov dword [eax+0x24], ebx                 ;eflag

     mov dword [eax+0x38], 0x2000-4            ;esp

     mov dword [eax+0x4c], 0x7                 ;cs(list-0,TI-1,RPL-3)

     mov dword [eax+0x50], 0x0f                ;ss(list-1,TI-1,RPL-3)

     mov dword [eax+0x54], 0x0f                ;ds(list-1,TI-1,RPL-3)

     mov ebx, [ebp + 16]

     add ebx, proc_ctrl.ldt_sel 

     mov cx, [ebx]

     mov word [eax+0x60], cx                   ;ldt选择子

     mov word [eax+0x66], 103                  ;TSS段长度

     ;将用户tss写入gdt

     call Set_TSS_sel

 

     ;修改进程状态为 正在运行

     mov eax, [ebp + 16]                       ;进程控制段

     add eax, proc_ctrl.state                  ;进程状态字段

     mov word [eax], task_running              ;进程状态字段设置为 正在运行             

 

     ;将进程控制段放入进程链表

     mov edx, [ebp + 16] 

     call mount_task_running_que

 

  ;将进程在gdt中的选择子写入进程结构进行保存

     mov edx, [ebp + 16] 

     mov [edx + proc_ctrl.task_sel], cx 

 

     ;绘制用户进程窗口 

     mov edx, [ebp + 16] 

     call draw_task_window

 

     add esp, 28    

 

     ret

 

;------------------------------------------------------------------------------- 

mount_task_running_que:                   ;将进程结构安装到运行队列中

                                          ;输入参数: edx--进程PROC_CTRL结构的偏移地址           

     cli                                  ;关中断

     pushad

    

     mov eax, [SYS_PROC + proc_ctrl.pre_task]  ;前一个进程结构地址

     mov [eax + proc_ctrl.next_task], edx      ;前一个进程的next指向新进程结构

     mov [SYS_PROC + proc_ctrl.pre_task], edx  ;系统进程的pre指向新进程结构

     mov [edx + proc_ctrl.pre_task], eax       ;新进程的pre指向前一个进程结构

     mov ebx, SYS_PROC                         ;新进程的next指向系统进程

     mov [edx + proc_ctrl.next_task], ebx     

 

     popad

     sti                                  ;开中断

     ret

;------------------------------------------------------------------------------- 

mount_task_run_to_pend_que:               ;将进程结构从就绪队列放入暂停队列 (在这里,由于系统进程不休眠,只有两个用户进程休眠,所以下面的代码偷懒了)           

                                          ;输入参数: edx--进程PROC_CTRL结构的偏移地址           

     cli                                  ;关中断

     pushad

     

     ;将进程结构从队列中取出

     mov eax, [edx + proc_ctrl.pre_task]  ;进程所在队列的前一个结构

     mov ebx, [edx + proc_ctrl.next_task] ;进程所在队列的后一个结构

     mov [_task_next], ebx                ;记录下一个进程结构地址

     mov [eax + proc_ctrl.next_task], ebx ;前一个结构的next指向后一个结构

     mov [ebx + proc_ctrl.pre_task], eax  ;后一个结构的pre指向前一个结构

     ;将进程结构放入pending队列

     cmp dword [_task_pend_que], 0x0      ;暂停队列是否为空

     jnz _chg_pnd_que1                    ;如果包含进程结构

     mov [_task_pend_que], edx            ;暂定队列头部指向该进程结构

     mov [edx + proc_ctrl.pre_task], edx  ;该进程结构的pre指向自己

     mov [edx + proc_ctrl.next_task], edx ;该进程结构的next指向自己

     jmp _chg_pnd_que2                    ;退出函数

 

_chg_pnd_que1:                            ;在这里,先被唤醒的放队列的前面,后被唤醒的放后面

     mov eax, dword[_task_pend_que]       ;eax指向暂定队列头部

     mov ecx, [edx + proc_ctrl.wakeup]    ;ecx指向新进程被唤醒的时刻值

     cmp ecx, [eax + proc_ctrl.wakeup]    ;和暂停队列头部比较唤醒时间大小

     jb _insert_head                      ;如果暂停时间小于头部时间,就插入暂停队列头部  

 

  ;插入暂停队列尾部

     mov ebx, [eax + proc_ctrl.pre_task]  ;ebx指向暂定队列的最后一个结构

     mov [ebx + proc_ctrl.next_task], edx ;队列最后一个结构的next指向本进程结构

     mov [eax + proc_ctrl.pre_task], edx  ;暂定队列头部的pre指向本进程结构

     mov [edx + proc_ctrl.pre_task], ebx  ;本进程结构的pre指向原队列最后一个结构

     mov [edx + proc_ctrl.next_task], eax ;本进程结构的next指向队列头部

     jmp _chg_pnd_que2

     ;插入暂停队列头部

_insert_head:

     mov eax, [_task_pend_que]            ;eax指向暂停队列头部

     mov [edx + proc_ctrl.next_task], eax ;本进程的next指向队列头部

     mov ebx, [eax + proc_ctrl.pre_task]  ;ebx指向暂定队列的最后一个结构

     mov [edx + proc_ctrl.pre_task], ebx

     mov [ebx + proc_ctrl.next_task], edx

     mov [eax + proc_ctrl.pre_task], edx

     mov [_task_pend_que], edx            ;暂停队列头部指向本结构

_chg_pnd_que2: 

     popad

     sti                                  ;开中断

 

     ;跳转到下一个就绪进程执行

     mov eax, [_task_next]                ;下一个进程结构地址

     mov [_task_now], eax                 ;当前进程

     add eax, proc_ctrl.task_rsvr

     jmp far [eax]                        ;跳转到新的进程执行

 

     ret

;------------------------------------------------------------------------------- 

mount_task_pend_to_run_que:               ;将进程结构从暂停队列放入就绪队列(就绪队列头部永远指向系统进程)            

                                          ;输入参数: edx--进程PROC_CTRL结构的偏移地址

     ;cli                                 ;关中断

     pushad

  ;先将进程结构从暂定队列取出

     mov edx, [_task_pend_que]            ;首先判断暂定队列是否只有一个结构

     mov eax, [edx + proc_ctrl.next_task] ;eax指向暂停队列头部的下一个结构

     cmp eax, edx                         ;如果暂停队列头部结构的next指向自己,暂停队列只有一个结构

     jnz _fix_pend_que_head 

     xor eax, eax

     mov [_task_pend_que], eax            ;暂停队列头部清空

     jmp _mount_to_run_que

_fix_pend_que_head:                       ;将暂停队列头部结构取出

     mov ebx, [edx + proc_ctrl.pre_task]  ;ebx指向暂停队列的尾部

     mov [ebx + proc_ctrl.next_task], eax ;尾部结构的next指向原队列的第二个结构

     mov [eax + proc_ctrl.pre_task], ebx  ;原队列的第二个结构的pre指向队列尾部结构

     mov [_task_pend_que], eax            ;暂停队列头部修改为原第二个结构地址

_mount_to_run_que: 

  ;将进程结构放入就绪队列

     mov eax, SYS_PROC                    ;eax指向系统进程

     mov ebx, [eax + proc_ctrl.pre_task]  ;ebx指向就绪队列最后一个结构

     mov [eax + proc_ctrl.pre_task], edx  ;系统进程的pre指向该进程结构

     mov [ebx + proc_ctrl.next_task], edx ;就绪队列最后一个结构的next指向该进程结构

     mov [edx + proc_ctrl.pre_task], ebx  ;该进程的pre指向队列原最后一个结构

     mov [edx + proc_ctrl.next_task], eax ;该进程的next指向系统进程结构 

 

     popad

     ;sti                                 ;开中断    

     ret 

 

;------------------------------------------------------------------------------- 

switch_task2:                               ;轮转切换当前执行的进程

    

     mov eax, [_task_now]                     ;eax指向当前进程

     mov ebx, [eax + proc_ctrl.next_task]     ;ebx指向下一个进程

     cmp eax, ebx                             ;是否是同一个进程

     je _switch_task_ok                       ;如果是同一个进程,无需切换

     mov [_task_now], ebx                     ;更新当前进程记录

     add ebx, proc_ctrl.task_rsvr

     jmp far [ebx]                            ;跳转到新的进程执行

_switch_task_ok:

     ret

;------------------------------------------------------------------------------- 

wakeup_task:                               ;检查进程休眠时间是否到时,并唤醒(在中断中处理,无需关中断)

    

     pushad 

     mov eax, [_task_pend_que]                ;eax指向休眠队列头部

     cmp eax, 0x0                             ;休眠队列是否为空

     jz wakeup_task_finished                  ;如果为空,直接跳出

     mov ebx, [sys_click]                     ;当前的系统时间

     mov ecx, [eax + proc_ctrl.wakeup]        ;ecx为进程被唤醒时间

     cmp ebx, ecx                             ;如果系统时间大于等于进程的唤醒时间

     jb wakeup_task_finished

     mov edx, eax                             ;调用时,edx指向被调整的进程地址

     call mount_task_pend_to_run_que        ;将进程结构从暂定队列放入就绪队列

   

wakeup_task_finished:

     popad

     ret 

;-------------------------------------------------------------------------------

draw_task_window:                             ;绘制用户进程窗口(窗口横梁宽度为5个点,其余都为一个点)

                                              ;输入:edx - 进程PROC_CTRL结构的偏移地址

     pushad

    

     ;窗口横梁,6个点宽

     xor eax, eax

     mov ax, 5                                ;eax高16位是y的高度

     shl eax, 16 

     mov ax, [edx + proc_ctrl.left_y]         ;eax低16位是y的值  

     xor ebx, ebx

     mov bx, [edx + proc_ctrl.len_x]          ;ebx高16位是x的宽度

     shl ebx, 16

     mov bx, [edx + proc_ctrl.left_x]         ;ebx低16位是x的值

     mov cl, 8

     call draw_rectangle                      ;画一个矩形

 

     ;窗口下梁,1个点宽

     xor eax, eax 

     mov ax, [edx + proc_ctrl.left_x]

     shl eax, 16 

     mov ax, [edx + proc_ctrl.left_y]

     add ax, [edx + proc_ctrl.len_y]

     xor ebx, ebx

     mov bx, [edx + proc_ctrl.len_x]

     mov cl, 8

     call draw_line 

     ;窗口左柱,1个点宽 

     xor eax, eax 

     mov ax, [edx + proc_ctrl.left_x]

     shl eax, 16 

     mov ax, [edx + proc_ctrl.left_y]

     xor ebx, ebx

     mov bx, [edx + proc_ctrl.len_y]

     mov cl, 8

     call draw_long_string 

     ;窗口右柱,1个点宽 

     xor eax, eax 

     mov ax, [edx + proc_ctrl.left_x]

     add ax, [edx + proc_ctrl.len_x]

     shl eax, 16 

     mov ax, [edx + proc_ctrl.left_y]

     xor ebx, ebx

     mov bx, [edx + proc_ctrl.len_y]

     inc bx

     mov cl, 8

     call draw_long_string

 

     ;窗口的退出按钮,大小为3×3的矩形

     xor eax, eax

     mov ax, 3                                ;eax高16位是y的高度

     shl eax, 16 

     mov ax, [edx + proc_ctrl.left_y]         ;eax低16位是y的值

     inc ax  

     xor ebx, ebx

     mov bx, 3                                ;ebx高16位是x的宽度

     shl ebx, 16

     mov bx, [edx + proc_ctrl.left_x]         ;ebx低16位是x的值

     add bx, [edx + proc_ctrl.len_x]

     sub bx, 4

     mov cl, 10                               ;暗绿

     call draw_rectangle                      ;画一个矩形     

    

     popad  

     ret            

 

;-------------------------------------------------------------------------------

read_hard_disk_0:                       ;从硬盘读取一个逻辑扇区(平坦模型)

          ;EAX=逻辑扇区号

          ;EBX=目标缓冲区线性地址

          ;返回:EBX=EBX+512

  cli

 

  push eax

  push ecx

  push edx

 

  push eax

 

  mov dx,0x1f2

  mov al,1

  out dx,al                          ;读取的扇区数

  inc dx                             ;0x1f3

  pop eax

  out dx,al                          ;LBA地址7~0

  inc dx                             ;0x1f4

  mov cl,8

  shr eax,cl

  out dx,al                          ;LBA地址15~8

  inc dx                             ;0x1f5

  shr eax,cl

  out dx,al                          ;LBA地址23~16

  inc dx                             ;0x1f6

  shr eax,cl

  or al,0xe0                         ;第一硬盘  LBA地址27~24

  out dx,al

  inc dx                             ;0x1f7

  mov al,0x20                        ;读命令

  out dx,al

.waits:

  in al,dx

  and al,0x88

  cmp al,0x08

  jnz .waits                         ;不忙,且硬盘已准备好数据传输

  mov ecx,256                        ;总共要读取的字数

  mov dx,0x1f0

.readw:

  in ax,dx

  mov [ebx],ax

  add ebx,2

  loop .readw

  pop edx

  pop ecx

  pop eax

 

  sti

 

  ret     

;--------------------------------全局变量---------------------------------------

align 4 

     _task_now        dd 0                    ;当前工作进程控制结构地址

     _task_next       dd 0                    ;当前工作进程的下一个结构

     _task_pend_que   dd 0x0                  ;暂停进程队列头

     _task_stop_que   dd 0x0                  ;停止进程队列头

     _task_old        dd 0                    ;保存上一个进程的控制结构地址 

     ;_task_window     dd 0                    ;按照顺序分配窗口(0-左下;1-右下;2-右上;左上角的窗口留给系统进程) 

 

SYS_PROC: 

     istruc proc_ctrl 

       at proc_ctrl.num,        resw    0 

       at proc_ctrl.state,      resw    0

       at proc_ctrl.wakeup,     resd    0

       at proc_ctrl.pre_task,   resd    0   

       at proc_ctrl.next_task,  resd    0   

       at proc_ctrl.task_rsvr,  resd    0

       at proc_ctrl.task_sel,   resw    0

       at proc_ctrl.ldt_rsvr,   resd    0

       at proc_ctrl.ldt_sel,    resw    0

       at proc_ctrl.ldt,        times   16 db 0

       at proc_ctrl.tss,     times   104 db 0

       at proc_ctrl.cmd,        times   8 db 0

       at proc_ctrl.sys_page,   resd    0

       at proc_ctrl.usr_page,   times   8 dd 0    

       at proc_ctrl.left_x,     resw    0

       at proc_ctrl.left_y,     resw    0

       at proc_ctrl.len_x,      resw    0

       at proc_ctrl.len_y,      resw    0   

     iend   

USR1_PROC: 

     istruc proc_ctrl 

       at proc_ctrl.num,        resw    0 

       at proc_ctrl.state,      resw    0

       at proc_ctrl.wakeup,     resd    0

       at proc_ctrl.pre_task,   resd    0   

       at proc_ctrl.next_task,  resd    0

       at proc_ctrl.task_rsvr,  resd    0

       at proc_ctrl.task_sel,   resw    0

       at proc_ctrl.ldt_rsvr,   resd    0

       at proc_ctrl.ldt_sel,    resw    0

       at proc_ctrl.ldt,        times   16 db 0

       at proc_ctrl.tss,     times   104 db 0

       at proc_ctrl.cmd,        times   8 db 0

       at proc_ctrl.sys_page,   resd    0

       at proc_ctrl.usr_page,   times   8 dd 0    

       at proc_ctrl.left_x,     resw    0

       at proc_ctrl.left_y,     resw    0

       at proc_ctrl.len_x,      resw    0

       at proc_ctrl.len_y,      resw    0

     iend

USR2_PROC: 

     istruc proc_ctrl 

       at proc_ctrl.num,        resw    0 

       at proc_ctrl.state,      resw    0

       at proc_ctrl.wakeup,     resd    0

       at proc_ctrl.pre_task,   resd    0   

       at proc_ctrl.next_task,  resd    0   

       at proc_ctrl.task_rsvr,  resd    0

       at proc_ctrl.task_sel,   resw    0

       at proc_ctrl.ldt_rsvr,   resd    0

       at proc_ctrl.ldt_sel,    resw    0

       at proc_ctrl.ldt,        times   16 db 0

       at proc_ctrl.tss,     times   104 db 0

       at proc_ctrl.cmd,        times   8 db 0

       at proc_ctrl.sys_page,   resd    0

       at proc_ctrl.usr_page,   times   8 dd 0    

       at proc_ctrl.left_x,     resw    0

       at proc_ctrl.left_y,     resw    0

       at proc_ctrl.len_x,      resw    0

       at proc_ctrl.len_y,      resw    0

     iend

align 4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: