范于渊归零露暖暖日常 自己动手写操作系统里面的话, 划线的这句话,我该怎么理解啊,感觉怎么读都不通顺啊。大神求解!

自由、创新、研究、探索
Linux/Windows Mono/DotNet [ Open Source .NET Development/ 使用开源工具进行DotNet软件开发]锐意进取,志存高远.成就梦想,只争朝夕.从你开始,创新世界.【That I exist is a perpetual supprise which is life. Focus on eCommerce】
《自己动手写操作系统》
今天看了于渊的《自己动手写操作系统》中的第一章,怎样10分钟写个操作系统,这个操作系统其实就是一个启动程序。
  当计算机电源被打开后,它会先进行加电自检(POST),然后寻找启动盘,如果是选择从软盘启动,计算机就会查找软盘的0面0磁道1扇区,如果发现它以0xAA55结束,则BIOS认为它是一个引导扇区,然后BIOS就会把引导扇区的前512字节的引导代码拷贝到内存的处并将控制器彻底交给这段引导代码。
  简单的引导代码如下所示:
org 07c00h ;告诉编译器加载到07c00h处
mov ax, cs
mov ds, ax
mov es, ax
call DispStr ;调用显示字符串函数
jmp $; 无限循环
11 DispStr:
mov ax, BootMessge
mov bp, ax
mov cx, 16
mov ax, 01301h
mov bx, 000ch
20 BootMessge: db "hello, OS world!"
21 times 510 - ($ - $$) db 0
22 dw 0aa55h
  这段代码时用nasm写的,它类似于masm的语言。org 07c00h命令就是将命令后面的代码中的偏移地址都加上07c00h,这样程序就相当于在出执行了。按书中所讲的,用命令nasm bootsector.asm -o boot.bin生成引导代码boot.bin,然后将boot.bin写入软盘的0面0磁道1扇区就可以了。问题就来了,我没有软盘怎么搞,不过在wmware虚拟机中貌似可以用软盘的映像文件来启动,所以就想到自己制作一个映像文件来代替软盘来作为启动盘,不过怎么创建这个映像文件呢?以前记得用linux下的dd命令做过linux的启动盘,dd应该是可以制作的,于是在网上找了下dd制作映像文件,果然是可以的,制作方法如下:
  1 先制作一个空的软盘映像文件diska.img(1.44Mb的软盘映像文件):  
  dd if=/dev/zero of=diska.img bs=512 count=2880
  2 制作一个包含boot.bin的映像文件boot.img:
  dd if=boot.bin of=boot.img bs=512 count=1
  3 将diska.img中1个扇区后面的数据拷贝到boot.img的后面
  dd if=diska.img of=boot.img skip=1 seek=1 bs=512 count=2879
  这样就做成了一个大小为1.44Mb的包含引导代码的映像文件。
  后面的事就好办了,直接在wmware创建一个空的虚拟机,在设置中将Floppy的路径设置为上面制作的引导扇区的路径就ok了,如下图那样:
  设置Floppy连接,断开CD/DVD连接,启动虚拟机就可以看到下面的画面了:
  总结:这个小的代码的编写和运行还是能让自己对系统启动有一个更深的认识,不过有个不懂的就是怎么用ISO镜像文件启动,怎么将引导代码写入ISO镜像文件,依然没有找到很好的方法解决。
阅读(...) 评论()
随笔 - 16271
评论 - 1458全面剖析《自己动手写操作系统》的pmtest1.asm
编辑:www.fx114.net
本篇文章主要介绍了"全面剖析《自己动手写操作系统》的pmtest1.asm",主要涉及到全面剖析《自己动手写操作系统》的pmtest1.asm方面的内容,对于全面剖析《自己动手写操作系统》的pmtest1.asm感兴趣的同学可以参考一下。
段机制轻松体验 内存寻址: 实模式下的内存寻址: 让我们首先来回顾实模式下的寻址方式 段首地址×16+偏移量 = 物理地址 为什么要×16?因为在8086CPU中,地址线是20位,但寄存器是16位的,最高寻址64KB,它无法寻址到1M内存。于是,Intel设计了这种寻址方式,先缩小4位成16位放入到段寄存器,用到时候,再将其扩大到20位,这也造成了段的首地址必须是16的倍数的限制。 公式:xxxx:yyyy 保护模式下分段机制的内存寻址: 分段机制是利用一个称作段选择符的偏移量,从而到描述符表找到需要的段描述符,而这个段描述符中就存放着真正的段的物理首地址,再加上偏移量 一段话,出现了三个新名词: 段选择子 描述符表 段描述符 ================================ 我们现在可以这样来理解这段话: 有一个结构体类型,它有三个成员变量: 段物理首地址 段界限 段属性 内存中,维护一个该结构体类型的数组。 而分段机制就是利用一个索引,找到该数组对应的结构体,从而得到段的物理首地址,然后加上偏移量,得到真正的物理地址。 公式:xxxx:yyyyyyyy 其中,xxxx也就是索引,yyyyyyyy是偏移量(因为32位寄存器,所以8个16进制)xxxx存放在段寄存器中。 ================================ 现在,我们来到过来分析一下那三个新名词: 段描述符:一个结构体,它有三个成员变量: 段物理首地址 段界限 段属性 描述符表:也就是一个数组,什么样的数组呢?是一个段描述符组成的数组。 段选择子: & 也就是数组的索引,但这时候的索引不在是高级语言中数组的下标,而是我们将要找的那个段描述符相对于数组首地址(也就是全局描述表的首地址)偏移位置。 就这么简单,如图: 图中,通过Selector(段选择子)找到存储在Descriptor Table(描述符表)中某个Descriptor(段描述符),该段描述符中存放有该段的物理首地址,所以就可以找到内存中真正的物理段首地址Segment Offset(偏移量):就是相对该段的偏移量 物理首地址 + 偏移量 就得到了物理地址 本图就是DATA 但这时,心细的朋友就发现了一个GDTR这个家伙还没有提到! 我们来看一下什么是GDTR Global Descriptor Table Register(全局描述符表寄存器) 但是这个寄存器有什么用呢 ? 大家想一下,段描述符表现在是存放在内存中,那CPU是如何知道它在哪里呢?所以,Iterl公司设计了一个全局描述符表寄存器,专门用来存放段描述符表的首地址,以便找到内存中段描述符表。 这时,段描述符表地址被存到GDTR寄存器中了。 ================================= 好了,分析就到这,我们来看一下正式的定义: 当x86 CPU 工作在保护模式时,可以使用全部32根地址线访问4GB的内存,因为80386的所有通用寄存器都是32位的,所以用任何一个通用寄存器来间接寻址,不比分段就可以访问4G空间中任意的内存地址。 但这并不意味着,此时段寄存器就不再有用了。实际上,段寄存器更加有用了,虽然再寻址上没有分段的限制了,但在保护模式下,一个地址空间是否可以被写入,可以被多少优先级的代码写入,是不是允许执行等等涉及保护的问题就出来了。要解决这些问题,必须对一个地址空间定义一些安全上的属性。段寄存器这时就派上了用场。但是设计属性和保护模式下段的参数,要表示的信息太多了,要用64位长的数据才能表示。我们把着64位的属性数据叫做段描述符,上面说过,它包含3个变量: 段物理首地址、段界限、段属性 80386的段寄存器是16位(注意:通用寄存器在保护模式下都是32位,但段寄存器没有被改变)的,无法放下保护模式下64位的段描述符。如何解决这个问题呢?方法是把所有段的段描述符顺序存放在内存中的指定位置,组成一个段描述符表(Descriptor Table);而段寄存器中的16位用来做索引信息,这时,段寄存器中的信息不再是段地址了,而是段选择子(Selector)。可以通过它在段描述符表中“选择”一个项目已得到段的全部信息。 那么段描述符表存放在哪里呢?80386引入了两个新的寄存器来管理段描述符,就是GDTR和LDTR,(LDTR大家先忘记它,随着学习的深入,我们会在以后学习)。 这样,用以下几步来总体体验下保护模式下寻址的机制 1、段寄存器中存放段选择子Selector 2、GDTR中存放着段描述符表的首地址 3、通过选择子根据GDTR中的首地址,就能找到对应的段描述符 4、段描述符中有段的物理首地址,就得到段在内存中的首地址 5、加上偏移量,就找到在这个段中存放的数据的真正物理地址。 好的,那我们开始编码,看看如何实现先前描述的内容 ================================= 首先,既然我们需要一个数组,全局描述符表,那我们就定义一块连续的结构体: [SECTION .gdt] ;为了代码可读性,我们将这个数组放到一个节中 ;由一块连续的地址组成的,不就是一个数组吗?看下面代码,^_^ 段基地址 段界限 段属性 GDT_BEGIN: Descriptor 0, & 0, 0 GDT_CODE32: Descriptor 0, 0, DA_C ;上面,我定义了二个连续地址的结构体,大家先认为Descriptor就是一个结构体类型,我们会在以后详细讲述 ;第一个结构体,全部是0,是为了遵循Interl规范,先记得就OK ;第二个定义了一个代码段,段基地址和段界限我们暂且还不知道,先初始化为0,但是因为是个代码段,代码段具备执行的属性,那么DA_C就代表是一个可执行代码段,DA_C是一个预先定义好的常量,我们会在详细讲解段描述符中讲解。 ================================= 我们继续来实现,那么下面,我们就需要设计段选择子了,因为上面代码已经包含了段描述符和全局描述符表 还记得选择子是个什么东西吗 ? 段选择子: & 也就是数组的索引,但这时候的索引不在是高级语言中数组的下标,而是我们将要找的那个段描述符相对于数组首地址(也就是全局描述表的首地址)偏移位置。 看我代码怎么实现,包含以上代码不再说明: [SECTION .gdt] GDT_BEGIN: Descriptor 0, 0, 0 GDT_CODE32: Descriptor 0, 0, DA_C ;下面是定义代码段选择子,它就是相对数组首地址的偏移量 SelectorCode32 equ GDT_CODE32 - GDT_BEGIN ;因为第一个段描述符,不被使用,所以就不比设置段选择子了。 ================================= 偏移地址: 注意一点,我们在程序中使用的都是偏移地址,相对于段的偏移地址,用上面的例子来说,象 GDT_CODE32 GDT_BEGIN 这些结构体的首地址都是相对于数据段的偏移量。什么意思呢 ? 因为我们的程序到底加载到内存的哪个地方是不固定,不知道的,只需使用偏移地址操作就行了,如: SelectorCode32 ,它本身就是一个偏移地址 但是SelectorCode32 equ GDT_CODE32 - GDT_BEGIN 怎么解释呢 ? GDT_CODE32是相对于数据段的偏移量, GDT_BEGIN也是相对于数据段的偏移量,虽然它是数组的首地址,说的罗索一些,GDT_BEGIN是数组的首地址,但是它是相对于数据段的偏移量 那么两个偏移量相减就是GDT_CODE32 相对于GDT_BEGIN的偏移量 所以,我们要时时刻刻记得,在程序中,我们永远使用的是偏移量,因为我们不知道程序将要被加载内存那块地方。 好了,基础也学的差不多了,下面我们要自己动手写一段程序,实现实模式到保护模式之间的跳转 ===================================================================== ;实现从实模式到保护模式之间的跳转 ;参考:《自己动手写操作系统》 ---------------------------------------------------------------------- %include "pm.inc" org 0100h jmp LABEL_BEGIN [SECTION .gdt] GDT_BEGIN: Descriptor 0, 0, & 0 GDT_CODE32: Descriptor 0, LenOfCode32 - 1, DA_C + DA_32 GDT_VIDEO: Descriptor 0B8000H, 0FFFFH, & DA_DRW GdtLen equ $ - GDT_BEGIN GdtPtr dw GdtLen - 1 dd 0 ;定义段选择子 SelectorCode32 equ GDT_CODE32 - GDT_BEGIN SelectorVideo equ GDT_VIDEO - GDT_BEGIN [SECTION .main] [BITS 16] LABEL_BEGIN: mov ax, cs mov ds, ax mov es, ax mov ss, ax ;初始化32位代码段选择子 ;我们可以在实模式下通过段寄存器×16 + 偏移两 得到物理地址, ;那么,我们就可以将这个物理地址放到段描述符中,以供保护模式下使用, ;因为保护模式下只能通过段选择子 + 偏移量 xor eax, eax mov ax, cs shl eax, 4 add eax, LABEL_CODE32 mov word [GDT_CODE32 + 2],ax shr eax, 16 mov byte [GDT_CODE32 + 4],al mov byte [GDT_CODE32 + 7],ah ;得到段描述符表的物理地址,并将其放到GdtPtr中 xor eax, eax mov ax, ds shl eax, 4 add eax, GDT_BEGIN mov dword [GdtPtr + 2],eax ;加载到gdtr,因为现在段描述符表在内存中,我们必须要让CPU知道段描述符 表在哪个位置 ;通过使用lgdtr就可以将源加载到gdtr寄存器中 lgdt [GdtPtr] ;关中断 cli ;打开A20线 in al, 92h or al, b out 92h, al ;准备切换到保护模式,设置PE为1 mov eax, cr0 or eax, 1 mov cr0, eax ;现在已经处在保护模式分段机制下,所以寻址必须使用段选择子:偏移量来 寻址 ;跳转到32位代码段中 ;因为此时偏移量位32位,所以必须dword告诉编译器,不然,编译器将阶段 成16位 jmp dword SelectorCode32:0;跳转到32位代码段第一条指令开始执行 [SECTION .code32] [BITS 32] LABEL_CODE32: mov ax, SelectorVideo mov es, ax xor edi, edi mov edi, (80 * 10 + 10) mov ah, 0ch mov al, 'G' mov [es:edi],ax jmp $ LenOfCode32 equ $ - LABEL_CODE32 =================================== 这段代码的大概意思是: 先在16位代码段,实模式下运行,在实模式下,通过段寄存器×16+偏移量得到32位代码的真正物理首地址,并将放入到段描述符表中,以供在保护模式下使用,上面说过了,保护模式下寻址,是通过段选择子,段描述符表,段描述符一起工作寻址的。所以在实模式下所做的工作就是初始化段描述符表里的所有段描述符。 我们来看一下段描述符表,它有3个段: GDT_BEGIN GDT_CODE32 GDT_VIDEO GDT_BEGIN,遵循Intel公司规定,全部置0 GDT_CODE32,32位代码段描述符,供保护模式下使用 GDT_VIDEO,显存段首地址,我们知道,显存首地址是0B8000H. 回想一下,我们在实模式下往显示器上输出文字时,我们设置段寄存器为 0B800h,(注意后面比真正物理地址少一个0)。 而我们现在在保护模式下访问显存,那么0B8000h就可以直接放到段描述符中即可。因为段描述符中存放的是段的真正的物理地址。 下面我们来逐行分析该代码 org 0100h 这句话告诉加载器,将这段程序加载到偏移段首地址0100h处,即:偏移256字节处,为什么要加载到偏移256个字节处呢 ?这是因为,在DOS中,需要留下256个字节和DOS系统进行通信。 jmp LABEL_BEGIN 执行这句话就跳转到LABEL_BEGIN处开始执行。 好,我们看一下LABEL_BEGIN在那块,也就是16位代码段 [SECTION .main] [BITS 16] LABEL_BEGIN: 这样程序就从.main节的第一段代码开始执行。 我们看一下上面的代码,[BITS 16]告诉编译器,这是一个16位代码段,所使用的寄存器都是16位寄存器。 该代码段初始化所有段描述符表中的段物理首地址 首先在实模式下计算出32位代码段的物理首地址 对照 段值 × 16 + 偏移量 = 物理地址 1 mov ax, cs 2 shl eax, 4 ;向左移动4位,不就是×16吗?呵呵 ;到现在为止,eax就是代码段的物理首地址了,那么。。。看 3 add eax, LABEL_CODE32 ;为eax (代码段首地址)加上 LABEL_CODE32偏移量,得到的不就是LABEL_CODE32的真正物理地址了吗 ?LABEL_CODE32在程序中,不就是32位代码段的首地址吗 ? 上面说过,代码中,使用的变量,或者标签 都是相对程序物理首地址的偏移量。 OK,现在我们已经知道了32位代码段的物理首地址,那么将eax放入到段描述符中就行了 我们先假设Descriptor就是一个结构体类型,(实际它是一个宏定义的数据结构,为了不影响整体思路,我们放到以后讲) 看一下这个Descriptor段描述符的内存模型: ; 高地址………………………………………………………………………低地址 ; | & 7 & | & 6 & | & 5 & | & 4 & | & 3 & | & 2 & | & 1 & | & 0 & | 共 8 字节 ; |--------========--------========--------========--------========| ; ┏━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┓ ; ┃31..24┃ & 段属性 & ┃ & 段基址(23..0) & ┃ 段界限(15..0)┃ ; ┃ & ┃ & & & ┃ & | & & & ┃ & & & ┃ ; ┃ 基址2┃ & & & ┃基址1b│ & 基址1a & ┃ & 段界限1 ┃ ; ┣━━━╋━━━┳━━━╋━━━━━━━━━━━╋━━━━━━━┫ ; ┃ & %6 ┃ %5 ┃ %4 ┃ %3 ┃ & %2 & ┃ & %1 & ┃ ; ┗━━━┻━━━┻━━━┻━━━┻━━━━━━━┻━━━━━━━┛ 由于历史原因,段描述符的内存排列不是按照 段基地址 段界限 段属性 这样的来排列的,所以我们现在要想一种办法,把eax里所存放的物理首地址拆开,分别放到2,3,4,7字节处 那么很显然,我们可以将eax寄存器中的ax先放到2,3字节处 mov word [GDT_CODE32 + 2],ax 因为在偏移2个字节处,所以,首地址 + 2,才能定位到下标为2的字节开头处 而,word 告诉编译器,我要一次访问2个字节的内存 好,简单的搞定了,那么再看,我们现在要将eax高16字节分别放到下标为4,7字节处。 虽然eax的ax代表低16位,但是Intel并没有给高位一个名字定义,(不会是high ax,呵呵),所以,我们没有办法去访问高位。但是我们可以将高16位放到低16位中,因为这时,低16位我们已经不关心它的值了。 好,看代码 shr eax, 16 这句代码就将eax向右移动16位,低位被抛弃,高位变成了低位。呵呵。。。 现在好办了,低16位又可以分为al,和 ah,那么现在我们就将al放到4位置,ah放到7位置吧 mov byte [GDT_CODE32 + 4], AL mov byte [GDT_CODE32 + 7], AH 不用我再解释这段代码了,自己去分析为什么吧。。。。 好了,32位代码段描述符设置好了,其界限设置看代码吧,为什么要那样设置,很简单的,界限 = 长度 - 1,段属性: DA_C: 98h & 可执行 DA_32: 4000h 32位代码段 是个常量,换算成二进制位,对照段描述符属性位置去看吧,参考任意一本保护模式书。 段描述符设置好了,但是,先段描述符表,还在内存中,我们必须想办法放到寄存器中,这时,就用到了gdtr(Golbal Descriptor Table Register),使用一条指令 lgdtr [GdtPtr] 就可以将GdtPtr加载到gdtr中 而gdtr的内存模型是: 高字节 & & & & & & & 低字节 但GdtPtr是什么呢 ? 就是我们定义的和这个寄存器内存模型一摸一样的结构体: GdtLen equ $ - LABEL_BEGIN GdtPtr dw GdtLen - 1 & ;界限 dd 0 & ;真正物理地址 那现在我们就要计算GdtPtr第二个字节 也就是真正物理地址了 xor eax, eax mov ax, ds shl eax, 4 add eax, GDT_BEGIN mov dword [GdtPtr + 2],eax 自己分析吧,和计算32位段首地址基本一样的, 搞定后,使用lgdt [GdtPtr]就将此加载到寄存器GDTR中了 然后关中断 cli 实模式下的中断和保护模式下的中断处理不一样,那就关吧,规矩 开启A20线 in al, 92h or al, b out 92h, al 如果不开启A20线,就无办法访问1M之上的内存,没办法,开启吧,规矩,想知道历史了,去查吧 然后设置CR0的PE位 mov eax, cr0 or eax, 1 mov cr0, eax 这个简单说一下,以后再详细 CR0也是一个寄存器,其中有个PE位,如果为0,就说明为实模式, 如果置1,说明为保护模式。现在我们要进入保护模式下工作,那么就要设置PE为1。 好了,看一下这个main节中的最后一个代码 jmp dword SelectorCode32 : 0 哈哈,现在已经再保护模式下了,当然要使用段选择子 + 偏移量来寻址啊,这样不就是寻址到了32位代码段中去了吗,偏移量为0不就说明从第一个代码开始执行。 不是吗 ?呵呵,那dword了? 因为现在的代码段是16位,编译器只能将它编译位16位,但处于保护模式下,它的偏移量应该是32位,所以,要显示告诉编译器,我这里使用的是32位,把我这块给编译成32位的!!! 如果不加dword, jmp SelectorCode32:0 这句话不会出什么问题,16位的0是0,32位的0还是0,但如果这样呢?: jmp SelectorCode32:0x 跳转到偏移0x中,这时就错了 如果不将dword,编译器就将该地址截断成16位,取低位,变成了0x5678 你说对吗 ?哈哈 所以我们必须这样做: jmp dword SelectorCodde32:0x OKEY,我们继续追击,执行完上面那个跳转后, 代码就跳到了32位代码段的中,开始执行第一条指令 mov ax, SelectorVideo 再看 mov es,ax 呵呵,实模式下,放的是16位的段值,而现在呢,不就是要将段选择子放到段寄存器里吗 ?然后通过段选择子(偏移量)找到描述符表中对应的段描述符的吗 !!!! 继续看下面代码 xor edi, edi mov edi, (80 * 10 + 10) mov ah, 0ch mov al, 'G' 跟实模式下差不多,设置目标10行10列 设置现实字符:G mov [es:edi],ax 也和实模式下一样, 只不过实模式是这样来寻址 : es×16 + edi 而保护模式下呢 es是一个偏移,根据这个偏移找到段描述符表中的对应显存段,然后这个显存段里存放的就是0B8000h,然后在加上偏移 不就的了吗!!! 哈哈 。。。。程序分析完毕,细节之处,自己体会去 总结: 1. 注意程序中使用的全部是偏移地址。注意两种偏移地址 A 对于程序的起始地址来说,所有变量和标签都是相对于整个程序的偏移量 B 对于段中定义的代码,有两种偏移: 相对于程序起始地址的偏移 相对于段标签的偏移。 2.不管是实模式下的物理地址,还是保护模式下的物理地址,反正他们都是物理地址,呵呵,实模式下求的物理地址,也能在保护模式下使用,只是他们不同的是,如何寻址的方式不一样。 3.一个程序中可以包含多个不同位的段,32位或者16位,他们之间也可以互相跳转,只是32位段用的是32位寄存器,16位代码段用的是16位寄存器,如果要在16位段下使用32位寄存器,必须象高级语言中强制类型转换一样,显示的定义 dword 参考: 《自动动手写操作系统》 《Undocument Windows 2000 Secrets》 《Linux 内核完全剖析》
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:&>&经典自己动手写操作系统
经典自己动手写操作系统
上传大小:2.55MB
这个比于渊的通俗,我自己看了,还不错。您下载了可以和本网站的那个比较比较。应该很容易学的。呵呵
综合评分:0(0位用户评分)
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, _username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click",'.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
上传者:zidane_2014
上传时间:积分/C币:3
上传者:ljw1252987
上传时间:积分/C币:3
上传者:liaoguol
上传时间:积分/C币:3
上传者:lj89168
上传时间:积分/C币:3
上传时间:积分/C币:5
上传者:conconcon1
上传时间:积分/C币:2
上传者:shen020453
上传时间:积分/C币:3
上传者:shen020453
上传时间:积分/C币:3
上传者:qqzhangchang
上传时间:积分/C币:3
上传者:jiakie
上传时间:积分/C币:3
上传者:aabb7012086
上传时间:积分/C币:10
上传者:EddyLee8208
上传时间:积分/C币:3
上传者:sdafsfwfwefe
上传时间:积分/C币:3
上传者:skyline_loafer
上传时间:积分/C币:5
上传者:sunjm200
上传时间:积分/C币:5
上传者:tiny_figure
上传时间:积分/C币:0
上传者:sunwei2323
上传时间:积分/C币:3
上传者:RockMolance
上传时间:积分/C币:3
上传者:wsllittlebird
上传时间:积分/C币:3
上传者:cuidandan09
上传时间:积分/C币:3
审核通过送C币
路面随机激励时域模型(MATLAB)
创建者:weixin_
广东工业大学考研真题及答案整理汇总
创建者:qq_
上百套精品PPT模板专题
创建者:fantasysxan
上传者其他资源上传者专辑
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
扫码关注并点击右下角获取下载码
输入下载码
为了良好体验,不建议使用迅雷下载
经典自己动手写操作系统
会员到期时间:
剩余下载个数:
剩余C币:593
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励5下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
经典自己动手写操作系统}

我要回帖

更多关于 范于渊和归零露 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信