• riscv gdb machine mode


    [root@centos7 04_interrupt]# cat src/head.s
     .section .text.init
         .align 3
         .globl _start
         .extern start_kernel
         .extern stack_top
         .extern _strap 
         .extern bss_start
         .extern bss_end
         .equ MTIMR, 0x200bff8
         .equ MTIMECMP, 0x2004000
    _start:
         csrci mstatus,8  
         li t0,0x1800  
         csrc mstatus,t0  
         li t0,0x800  
         csrs mstatus,t0  
         li t0,0x888  
         csrc mie,t0
         la t0,fail1  
         csrw mtvec,t0  
         la t0,super  
         csrw mepc,t0
         
    lean_bss:  
             la t0, bss_start  
             la t1, bss_end  
             li t2,0
    clean_loop:
         sw t2, 0(t0)
         addi t0, t0, 1
         bne t0, t1, clean_loop
         
    init_mtimecpp:
         li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
         ld t0,0(t2)
         li t1,0x100000
         add t0, t0, t1
         li t1, MTIMECMP
         sd t0, 0(t1)
    open_interupt:
         li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
         csrs mstatus, t0  
         li t0,0x0A0  
         csrs mie, t0
         li t0,0x20
         csrs mideleg, t0  
         mret    # 转入super
         
    super: 
        la t0,st_reg 
        csrw stvec,t0
        la sp,stack_top  
        call t0,start_kernel
        
    fail1:
        csrr a1,mcause
        li t0,0x8000000000000007   
         /* check the mcause to see if it's a time trap*/
        beq a1,t0,is_a_trap  //中断委托代理
        li t2,MTIMECMP
          /* ecall from S so mtimecpp+=fff000/enable mie/disable mip */
        ld t0,0(t2)  
        li t1,0xfff000  
        add t0, t0, t1  
        sd t0, 0(t2)  
        li t0,0x80  
        csrs mie, t0  
        li t0,0x20  
        csrc mip,t1  
        csrr t0,mepc   ##更新mepc
        addi t0, t0, 4  
        csrw mepc,t0  
        mret
    is_a_trap:
        li t0,0x80                   /* time trap so enable mip/disable mie */
        csrc mie, t0  
        li t0,0x20  
        csrs mip,t0  
        mret

     

     

         csrci mstatus,8  #MPIE清零
         li t0,0x1800  
         csrc mstatus,t0  #MPP=00
         li t0,0x800  
         csrs mstatus,t0  #MPP=01 s模式
         li t0,0x888  
         csrc mie,t0
         la t0,fail1  
         csrw mtvec,t0  
         la t0,super  
         csrw mepc,t0
    • machine mode处理函数分析异常原因,判断为时钟中断,为了将时钟中断委托给supervisor mode,于是将mip[stip]置位,并且为了防止在supervisor mode处理时钟中断时继续触发machine mode时钟中断,于是同时将mie[mtie]清零。

    is_a_trap:
        li t0,0x80                   /* time trap so enable mip/disable mie */
        csrc mie, t0  #disable  mie time
        li t0,0x20  
        csrs mip,t0  #enable sTIP
        mret

    当处理同步异常时应该在退出前给mepc+4,当处理中断时则不需要,请解释为什么要这样做。
    mepc储存返回地址。出现同步异常后,返回地址更新为当前发生异常指令的地址,但是真正的返回地址应该是异常指令的下一条指令,故要执行mepc=mepc+4。处理中断时,mepc已储存下一条指令地址,故不需要自增。

      csrr t0,mepc   ##更新mepc
        addi t0, t0, 4  
        csrw mepc,t0  
        mret

    整个代码没有设置xepc等价于

    mip 寄存器

    mip 寄存器指示了何种类型的中断正在传入 (pending),与它相同功能的寄存器有 sip 和 uip 。

    在该寄存器中,只有低特权级别的软件中断位 (USIP, SSIP)、时钟中断 (UTIP, STIP) 、外部中断 (UEIP, SEIP) 是可以通过 CSR 指令写入的,其他都是只读的。若有中断委托给了权限级别 x ,被委托的中断所对应的位(在 xie 和 xip 寄存器中)就可以使用了,否则,相应的位接地变 0

    xTIP: timer interrupt-pending bit in x mode 时钟中断
    xSIP: software interrupts in x mode 软件中断
    xEIP: external interrupt 外部中断

    请注意,MTIP 、STIP 、UTIP 位分别对应机器模式、监管者模式、用户模式的时钟中断信号。MTIP 位是只读的,而 UTIP 和 STIP 位在机器模式下可以写入,这就是将时钟中断处理下放给低级权限的方式。

    mie 寄存器 

    mie 寄存器包含了相应的中断使能位,sie 和 uie 功能相似。注意观察 mcause 寄存器编码,可以发现,若 bit i 在 mie 和 mip 寄存器都置位,且全局中断位打开,那么中断 i 就会视作发生,并被处理。一般情况下,在低权限运行时,机器模式的中断一直有效。

    xTIE: timer interrupt-enable bit in x mode 时钟中断使能位
    xSIE: software interrupt-enable in x mode 软件中断使能位
    xEIE: external interrupt-enable in x mode 外部中断使能位

    注: WPRI: Write Preserve values, Reads Ignore values. 保留值
    xIE: Interrupt Enable in x mode 中断使能
    xPIE: Previous Interrupt Enable in x mode 之前的中断使能
    xPP: Previous Privilege mode up to x mode 之前的特权级别

    在中断使能方面,MIE 、SIE 、UIE 分别提供了 machine mode 、supervisor mode 、user mode 的全局中断使能位,若一个 hart 运行在特权级别 x 下,当 xIE = 1 时中断全局打开,反之则关闭。在 hart 于 x 运行时,无论 wIE 为何值,低权限中断 w < x 总是无效的,而无论 yIE 为何值,高权限中断 y > x 总是有效。

    mcause 寄存器 

    mcause 寄存器的作用是记录中断/异常事件的类型/起因。在当 trap 进入机器模式后,将异常/中断事件产生的起因(或者称之为谁导致了异常/中断事件)写入到该寄存器中。

    mcause 寄存器编码形式,首位为 1 时是中断,0 时为异常
    mcause 寄存器对应事件表
    fail1:
        csrr a1,mcause
        li t0,0x8000000000000007   
         /* check the mcause to see if it's a time trap*/
        beq a1,t0,is_a_trap  ##相等
        li t2,MTIMECMP
          /* ecall from S so mtimecpp+=fff000/enable mie/disable mip */
        ld t0,0(t2)  
        li t1,0xfff000  
        add t0, t0, t1  
        sd t0, 0(t2)  
        li t0,0x80  
        csrs mie, t0  
        li t0,0x20  
        csrc mip,t1  
        csrr t0,mepc   
        addi t0, t0, 4  
        csrw mepc,t0  
        mret
    is_a_trap:
        li t0,0x80                   /* time trap so enable mip/disable mie */
        csrc mie, t0  #disable  mie time
        li t0,0x20  
        csrs mip,t0  #enable sTIP
        mret
     [root@centos7 04_interrupt]# riscv64-unknown-elf-gdb -x debug.txt
    GNU gdb (GDB) 11.1
    Copyright (C) 2021 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "--host=aarch64-unknown-linux-gnu --target=riscv64-unknown-elf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <https://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.
    
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    warning: Can not parse XML target description; XML support was disabled at compile time
    0x0000000000001000 in ?? ()
    (gdb) b _start
    Breakpoint 1 at 0x80000000: file src/head.s, line 12.
    (gdb) b lean_bss
    Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
    (gdb) b clean_loop
    Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
    (gdb) b init_mtimecpp
    Breakpoint 4 at 0x80000056: file src/head.s, line 34.
    (gdb) b open_interupt
    Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
    (gdb) b super
    Breakpoint 6 at 0x80000088: file src/head.s, line 50.
    (gdb) b fail1
    Breakpoint 7 at 0x800000a0: file src/head.s, line 56.
    (gdb) b is_a_trap
    Breakpoint 8 at 0x800000e0: file src/head.s, line 75.
    (gdb) c
    Continuing.
    
    Breakpoint 1, _start () at src/head.s:12
    12           csrci mstatus,8  
    (gdb) c
    Continuing.
    
    Breakpoint 2, lean_bss () at src/head.s:25
    25               la t0, bss_start  
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 4, init_mtimecpp () at src/head.s:34
    34           li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
    (gdb) c
    Continuing.
    
    Breakpoint 5, open_interupt () at src/head.s:41
    41           li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
    (gdb) c
    Continuing.
    
    Breakpoint 6, super () at src/head.s:50
    50              la t0,st_reg 
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 8, is_a_trap () at src/head.s:75
    75          li t0,0x80                   /* time trap so enable mip/disable mie */
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 7, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) cc
    [root@centos7 04_interrupt]# cat src/entry.s
    .section .text.entry
         .align 3
         .global st_reg  
         .global ld_reg  
         .global myentry  
         .extern strap_c
         
    st_reg:
         sd sp, -8(sp)  
         sd ra, -16(sp)  
         sd gp, -24(sp)  
         sd tp, -32(sp)  
         sd t0, -40(sp)  
         sd t1, -48(sp)  
         sd t2, -56(sp)
         sd s0, -64(sp)  
         sd s1, -72(sp)  
         sd a0, -80(sp)  
         sd a1, -88(sp)  
         sd a2, -96(sp)  
         sd a3, -104(sp)  
         sd a4, -112(sp)  
         sd a5, -120(sp)  
         sd a6, -128(sp)  
         sd a7, -136(sp)  
         sd s2, -144(sp)  
         sd s3, -152(sp)  
         sd s4, -160(sp)  
         sd s5, -168(sp)  
         sd s6, -176(sp)  
         sd s7, -184(sp)  
         sd s8, -192(sp)  
         sd s9, -200(sp)  
         sd s10, -208(sp) 
         sd s11, -216(sp) 
         sd t3, -224(sp)  
         sd t4, -232(sp)  
         sd t5, -240(sp)  
         sd t6, -248(sp)  
         addi sp, sp, -248
         
    myentry: 
             call strap_c  
             ecall
         
    ld_reg: 
         ld t6, 0(sp)  
         ld t5, 8(sp)  
         ld t4, 16(sp)  
         ld t3, 24(sp)  
         ld s11, 32(sp)  
         ld s10, 40(sp)  
         ld s9, 48(sp)  
         ld s8, 56(sp)  
         ld s7, 64(sp)  
         ld s6, 72(sp)  
         ld s5, 80(sp)  
         ld s4, 88(sp)  
         ld s3, 96(sp)  
         ld s2, 104(sp)  
         ld a7, 112(sp)  
         ld a6, 120(sp)  
         ld a5, 128(sp)  
         ld a4, 136(sp)  
         ld a3, 144(sp)  
         ld a2, 152(sp)  
         ld a1, 160(sp)  
         ld a0, 168(sp)  
         ld s1, 176(sp)  
         ld s0, 184(sp)  
         ld t2, 192(sp)  
         ld t1, 200(sp)  
         ld t0, 208(sp)
         ld tp, 216(sp)  
         ld gp, 224(sp)  
         ld ra, 232(sp)  
         ld sp, 240(sp)  
         sret
    [root@centos7 04_interrupt]# qemu-system-riscv64 -M virt -kernel kernel.img -bios none -serial stdio -s -S
    VNC server running on ::1:5900
    ZJU OS LAB 2             GROUP-05
    [S] Supervisor Mode Timer Interrupt 
    [S] Supervisor Mode Timer Interrupt 
    [S] Supervisor Mode Timer Interrupt 
    [S] Supervisor Mode Timer Interrupt 
    qemu-system-riscv64: terminating on signal 2
    [root@centos7 04_interrupt]# cat debug.txt 
    file kernel.elf
    target remote :1234
     b _start
     b lean_bss
     b clean_loop
     b init_mtimecpp
     b open_interupt
     b super
     b st_reg
     b myentry
     b strap_c
     b ld_reg
     b fail1
     b is_a_trap
    [root@centos7 04_interrupt]# riscv64-unknown-elf-gdb -x debug.txt
    GNU gdb (GDB) 11.1
    Copyright (C) 2021 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "--host=aarch64-unknown-linux-gnu --target=riscv64-unknown-elf".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <https://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.
    
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    warning: Can not parse XML target description; XML support was disabled at compile time
    0x0000000000001000 in ?? ()
    Breakpoint 1 at 0x80000000: file src/head.s, line 12.
    Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
    Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
    Breakpoint 4 at 0x80000056: file src/head.s, line 34.
    Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
    Breakpoint 6 at 0x80000088: file src/head.s, line 50.
    Breakpoint 7 at 0x800000f8: file src/entry.s, line 9.
    Breakpoint 8 at 0x80000178: file src/entry.s, line 43.
    Breakpoint 9 at 0x8000031c: file src/strap.c, line 6.
    Breakpoint 10 at 0x80000180: file src/entry.s, line 47.
    Breakpoint 11 at 0x800000a0: file src/head.s, line 56.
    Breakpoint 12 at 0x800000e0: file src/head.s, line 75.
    (gdb) c
    Continuing.
    
    Breakpoint 1, _start () at src/head.s:12
    12           csrci mstatus,8  
    (gdb) c
    Continuing.
    
    Breakpoint 2, lean_bss () at src/head.s:25
    25               la t0, bss_start  
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 3, clean_loop () at src/head.s:29
    29           sw t2, 0(t0)
    (gdb) c
    Continuing.
    
    Breakpoint 4, init_mtimecpp () at src/head.s:34
    34           li t2,MTIMR                /* mtimecpp=mtimr+100000 */  
    (gdb) c
    Continuing.
    
    Breakpoint 5, open_interupt () at src/head.s:41
    41           li t0,0x0A                  /* set [m/s]staus & [m/s]ie & mideleg */
    (gdb) c
    Continuing.
    
    Breakpoint 6, super () at src/head.s:50
    50              la t0,st_reg 
    (gdb) c
    Continuing.
    
    Breakpoint 11, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 12, is_a_trap () at src/head.s:75
    75          li t0,0x80                   /* time trap so enable mip/disable mie */
    (gdb) c
    Continuing.
    
    Breakpoint 7, st_reg () at src/entry.s:9
    9            sd sp, -8(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 8, myentry () at src/entry.s:43
    43               call strap_c  
    (gdb) c
    Continuing.
    
    Breakpoint 9, strap_c () at src/strap.c:6
    6            count0++;
    (gdb) c
    Continuing.
    
    Breakpoint 11, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 10, ld_reg () at src/entry.s:47
    47           ld t6, 0(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 7, st_reg () at src/entry.s:9
    9            sd sp, -8(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 8, myentry () at src/entry.s:43
    43               call strap_c  
    (gdb) c
    Continuing.
    
    Breakpoint 9, strap_c () at src/strap.c:6
    6            count0++;
    (gdb) c
    Continuing.
    
    Breakpoint 11, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 10, ld_reg () at src/entry.s:47
    47           ld t6, 0(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 7, st_reg () at src/entry.s:9
    9            sd sp, -8(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 8, myentry () at src/entry.s:43
    43               call strap_c  
    (gdb) c
    Continuing.
    
    Breakpoint 9, strap_c () at src/strap.c:6
    6            count0++;
    (gdb) c
    Continuing.
    
    Breakpoint 11, fail1 () at src/head.s:56
    56          csrr a1,mcause
    (gdb) c
    Continuing.
    
    Breakpoint 10, ld_reg () at src/entry.s:47
    47           ld t6, 0(sp)  
    (gdb) c
    Continuing.
    
    Breakpoint 7, st_reg () at src/entry.s:9
    9            sd sp, -8(sp)  
    (gdb) cc
    Undefined command: "cc".  Try "help".
    (gdb) q
    A debugging session is active.
    
            Inferior 1 [process 1] will be detached.
    
    Quit anyway? (y or n) y

     

    0x0000000000001000 in ?? ()
    Breakpoint 1 at 0x80000000: file src/head.s, line 12.
    Breakpoint 2 at 0x8000003a: file src/head.s, line 25.
    Breakpoint 3 at 0x8000004c: file src/head.s, line 29.
    Breakpoint 4 at 0x80000056: file src/head.s, line 34.
    Breakpoint 5 at 0x8000006e: file src/head.s, line 41.
    Breakpoint 6 at 0x80000088: file src/head.s, line 50.
    Breakpoint 7 at 0x800000f8: file src/entry.s, line 9.
    Breakpoint 8 at 0x800001ce: file src/main.c, line 7.
    Breakpoint 9 at 0x80000178: file src/entry.s, line 43.
    Breakpoint 10 at 0x8000031c: file src/strap.c, line 6.
    Breakpoint 11 at 0x80000180: file src/entry.s, line 46.
    Breakpoint 12 at 0x800000a0: file src/head.s, line 56.
    Breakpoint 13 at 0x800000e0: file src/head.s, line 75.
    (gdb) b src/entry.s:77
    Breakpoint 14 at 0x800001be: file src/entry.s, line 77.
    (gdb) c

    fail mret

     

    ld_reg ret返回

     

     is_a_trap mret返回

     

    更改 is_a_trap

    is_a_trap:
        li t0,0x80                   /* time trap so enable mip/disable mie */
        csrc mie, t0  #disable  mie time
        li t0,0x20  
        csrs mip,t0  #enable sTIP
        mret

     

     

  • 相关阅读:
    程序员之痛:几千行代码能搞定的为什么要写几万行?
    python基础===新式类与经典类
    python基础===装饰器@property 的扩展
    java===java基础学习(16)---final
    java===java基础学习(15)---抽象,接口
    python基础===继承和多继承
    python基础===类的私有属性(伪私有)
    python基础===创建大量对象是节省内存方法
    java===java习题---Josephu问题
    java===java基础学习(14)---封装
  • 原文地址:https://www.cnblogs.com/dream397/p/15689980.html
Copyright © 2020-2023  润新知