鴻蒙內(nèi)核源碼分析(工作模式篇) | CPU的七種工作模式

本篇說(shuō)清楚CPU的工作模式

工作模式(Working mode) 也叫操作模式(Operating mode)又叫處理器模式(Processor mode),是 CPU 運(yùn)行的重要參數(shù),決定著處理器的工作方式,比如如何裁決特權(quán)級(jí)別和報(bào)告異常等。
系列篇為方便理解,統(tǒng)一叫工作模式,CPU的工作模式.

正如一個(gè)互聯(lián)網(wǎng)項(xiàng)目的后臺(tái)管理系統(tǒng)有權(quán)限管理一樣,CPU工作是否也有權(quán)限(模式)? 一個(gè)成熟的軟硬件架構(gòu),肯定會(huì)有這些設(shè)計(jì),只是大部分人不知道,也不需要知道,老百姓就干好老百姓的活就行了,有工作能吃飽飯就知足了,宮的事你管那么多干嘛,你也管不了.

應(yīng)用程序就只關(guān)注應(yīng)用功能,業(yè)務(wù)邏輯相關(guān)的部分就行了,底層實(shí)現(xiàn)對(duì)應(yīng)用層屏蔽的越干凈系統(tǒng)設(shè)計(jì)的就越優(yōu)良.

但鴻蒙內(nèi)核源碼分析系列篇的定位就是要把整個(gè)底層解剖,全部掰開(kāi),看看宮里究竟發(fā)生了么事.從本篇開(kāi)始要接觸大量的匯編的代碼,將鴻蒙內(nèi)核的每段匯編代碼一一說(shuō)明白.如此才能知道最開(kāi)始的開(kāi)始發(fā)生了什么,最后的最后又發(fā)生了什么.

七種模式

先看一張圖,圖來(lái)源于 ARM720T.pdf第43頁(yè),在ARM體系中,CPU很像有七個(gè)老婆的韋小寶,工作在以下七種模式中:

  • 用戶模式(usr):該模式是用戶程序的工作模式,它運(yùn)行在操作系統(tǒng)的用戶態(tài),它沒(méi)有權(quán)限去操作其它硬件資源,只能執(zhí)行處理自己的數(shù)據(jù),也不能切換到其它模式下,要想訪問(wèn)硬件資源或切換到其它模式只能通過(guò)軟中斷或產(chǎn)生異常。

  • 快速中斷模式(fiq):快速中斷模式是相對(duì)一般中斷模式而言的,用來(lái)處理高優(yōu)先級(jí)中斷的模式,處理對(duì)時(shí)間要求比較緊急的中斷請(qǐng)求,主要用于高速數(shù)據(jù)傳輸及通道處理中。

  • 普通中斷模式(irq):一般中斷模式也叫普通中斷模式,用于處理一般的中斷請(qǐng)求,通常在硬件產(chǎn)生中斷信號(hào)之后自動(dòng)進(jìn)入該模式,該模式可以自由訪問(wèn)系統(tǒng)硬件資源。

  • 管理模式(svc):操作系統(tǒng)保護(hù)模式,CPU上電復(fù)位和當(dāng)應(yīng)用程序執(zhí)行 SVC 指令調(diào)用系統(tǒng)服務(wù)時(shí)也會(huì)進(jìn)入此模式,操作系統(tǒng)內(nèi)核的普通代碼通常工作在這個(gè)模式下。

  • 終止模式(abt):當(dāng)數(shù)據(jù)或指令預(yù)取終止時(shí)進(jìn)入該模式,中止模式用于支持虛擬內(nèi)存或存儲(chǔ)器保護(hù),當(dāng)用戶程序訪問(wèn)非法地址,沒(méi)有權(quán)限讀取的內(nèi)存地址時(shí),會(huì)進(jìn)入該模式,

  • 系統(tǒng)模式(sys):供操作系統(tǒng)使用的高特權(quán)用戶模式,與用戶模式類似,但具有可以直接切換到其他模式等特權(quán),用戶模式與系統(tǒng)模式兩者使用相同的寄存器,都沒(méi)有SPSR(Saved Program Statement Register,已保存程序狀態(tài)寄存器),但系統(tǒng)模式比用戶模式有更高的權(quán)限,可以訪問(wèn)所有系統(tǒng)資源。

  • 未定義模式(und):未定義模式用于支持硬件協(xié)處理器的軟件仿真,CPU在指令的譯碼階段不能識(shí)別該指令操作時(shí),會(huì)進(jìn)入未定義模式。

除用戶模式外,其余6種工作模式都屬于特權(quán)模式

  • 特權(quán)模式中除了系統(tǒng)模式以外的其余5種模式稱為異常模式
  • 大多數(shù)程序運(yùn)行于用戶模式
  • 進(jìn)入特權(quán)模式是為了處理中斷、異常、或者訪問(wèn)被保護(hù)的系統(tǒng)資源
  • 硬件權(quán)限級(jí)別:系統(tǒng)模式 > 異常模式 > 用戶模式
  • 快中斷(fiq)與慢中斷(irq)區(qū)別:快中斷處理時(shí)禁止中斷

每種模式都有自己獨(dú)立的入口和獨(dú)立的運(yùn)行棧空間. 系列篇之CPU篇 已介紹過(guò)只要提供了入口函數(shù)和運(yùn)行空間,CPU就可以干活了.入口函數(shù)解決了指令來(lái)源問(wèn)題,運(yùn)行空間解決了指令的運(yùn)行場(chǎng)地問(wèn)題.
而且在多核情況下,每個(gè)CPU核的每種特權(quán)模式都有自己獨(dú)立的棧空間.注意是特權(quán)模式下的棧空間,用戶模式的棧空間是由用戶(應(yīng)用)程序提供的.

如何讓這七種模式能流暢的跑起來(lái)呢? 至少需要以下解決三個(gè)基本問(wèn)題.

  • 棧空間是怎么申請(qǐng)的?申請(qǐng)了多大?
  • 被切換中的模式代碼放在哪里?誰(shuí)來(lái)安排它們放在哪里?
  • 模式之間是怎么切換的?狀態(tài)怎么保存?

這個(gè)匯編文件大概 500多行,非常重要,本篇受限于篇幅只列出一小部分,說(shuō)清楚以上三個(gè)問(wèn)題.系列其余篇中將詳細(xì)說(shuō)明每段匯編代碼的作用和實(shí)現(xiàn),可前往查閱.

1.異常模式棧空間怎么申請(qǐng)?

鴻蒙是如何給異常模式申請(qǐng)棧空間的

#define CORE_NUM                 LOSCFG_KERNEL_SMP_CORE_NUM //CPU 核數(shù)
#ifdef LOSCFG_GDB
#define OS_EXC_UNDEF_STACK_SIZE  512
#define OS_EXC_ABT_STACK_SIZE    512
#else
#define OS_EXC_UNDEF_STACK_SIZE  40
#define OS_EXC_ABT_STACK_SIZE    40
#endif
#define OS_EXC_FIQ_STACK_SIZE    64
#define OS_EXC_IRQ_STACK_SIZE    64
#define OS_EXC_SVC_STACK_SIZE    0x2000 //8K
#define OS_EXC_STACK_SIZE        0x1000 //4K

@六種特權(quán)模式申請(qǐng)對(duì)應(yīng)的棧運(yùn)行空間
__undef_stack:
    .space OS_EXC_UNDEF_STACK_SIZE * CORE_NUM 
__undef_stack_top:

__abt_stack:
    .space OS_EXC_ABT_STACK_SIZE * CORE_NUM
__abt_stack_top:

__irq_stack:
    .space OS_EXC_IRQ_STACK_SIZE * CORE_NUM 
__irq_stack_top:

__fiq_stack:
    .space OS_EXC_FIQ_STACK_SIZE * CORE_NUM
__fiq_stack_top:

__svc_stack:
    .space OS_EXC_SVC_STACK_SIZE * CORE_NUM 
__svc_stack_top:

__exc_stack:
    .space OS_EXC_STACK_SIZE * CORE_NUM
__exc_stack_top:

代碼解讀

  • 六種異常模式都有自己獨(dú)立的棧空間
  • 每種模式的OS_EXC_***_STACK_SIZE棧大小都不一樣,最大是管理模式(svc)8K,最小的只有40個(gè)字節(jié). svc模式為什么要這么大呢?
    因?yàn)殚_(kāi)機(jī)代碼和系統(tǒng)調(diào)用代碼的運(yùn)行都在管理模式,系統(tǒng)調(diào)用的函數(shù)實(shí)現(xiàn)往往較復(fù)雜,最大不能超過(guò)8K.
    例如:某個(gè)系統(tǒng)調(diào)用中定義一個(gè)8K的局部變量,內(nèi)核肯定立馬閃蹦.因?yàn)闂⒁绯觯幚懋惓5某绦虺霈F(xiàn)了異常,后面就再也沒(méi)人兜底了,只能是死局.
  • 鴻蒙是支持多核處理的,CORE_NUM表明,每個(gè)CPU核的每種異常模式都有自己的獨(dú)立棧空間.注意理解這個(gè)是理解內(nèi)核代碼的基礎(chǔ).否則會(huì)一頭霧水.

2.異常模式入口地址在哪?

再看一張圖,圖來(lái)源于 ARM720T.pdf 第56頁(yè)

這就是一切一切的開(kāi)始,指定所有異常模式的入口地址表,這就是規(guī)定,沒(méi)得商量的.在低地址情況下.開(kāi)機(jī)代碼就是放在 0x00000000的位置, 觸發(fā)開(kāi)機(jī)鍵后,硬件將PC寄存器置為0x00000000,開(kāi)始了萬(wàn)里長(zhǎng)征的第一步.在系統(tǒng)運(yùn)行過(guò)程中就這么來(lái)回跳.

    b   reset_vector            @開(kāi)機(jī)代碼
    b   _osExceptUndefInstrHdl  @異常處理之CPU碰到不認(rèn)識(shí)的指令
    b   _osExceptSwiHdl         @異常處理之:軟中斷
    b   _osExceptPrefetchAbortHdl   @異常處理之:取指異常
    b   _osExceptDataAbortHdl       @異常處理之:數(shù)據(jù)異常
    b   _osExceptAddrAbortHdl       @異常處理之:地址異常
    b   OsIrqHandler                @異常處理之:硬中斷
    b   _osExceptFiqHdl             @異常處理之:快中斷

以上是各個(gè)異常情況下的入口地址,在reset_vector_mp.S中都能找到,經(jīng)過(guò)編譯鏈接后就會(huì)變成

    b   0x00000000      @開(kāi)機(jī)代碼
    b   0x00000004      @異常處理之CPU碰到不認(rèn)識(shí)的指令
    b   0x00000008      @異常處理之:軟中斷
    b   0x0000000C      @異常處理之:取指異常
    b   0x00000010      @異常處理之:數(shù)據(jù)異常
    b   0x00000014      @異常處理之:地址異常
    b   0x00000018      @異常處理之:硬中斷
    b   0x0000001C      @異常處理之:快中斷

不管是主動(dòng)切換的異常,還是被動(dòng)切換的異常,都會(huì)先跳到對(duì)應(yīng)的入口去處理.每個(gè)異常的代碼都起始于匯編,處理完了再切回去.舉個(gè)例子:
某個(gè)應(yīng)用程序調(diào)用了系統(tǒng)調(diào)用(比如創(chuàng)建定時(shí)器),會(huì)經(jīng)過(guò)以下大致過(guò)程:

  • swi指令將用戶模式切換到管理模式(svc)
  • 在管理模式中先保存用戶模式的現(xiàn)場(chǎng)信息(R0-R15寄存器值入棧)
  • 獲取系統(tǒng)調(diào)用號(hào),知道是調(diào)用了哪個(gè)系統(tǒng)調(diào)用
  • 查詢系統(tǒng)調(diào)用對(duì)應(yīng)的注冊(cè)函數(shù)
  • 執(zhí)行真正的創(chuàng)建定時(shí)器函數(shù)
  • 執(zhí)行完成后,恢復(fù)用戶模式的現(xiàn)場(chǎng)信息(R0-R15寄存器值出棧)
  • 跳回用戶模式繼續(xù)執(zhí)行

各異常處理代碼很多,不一一列出,本篇只列出開(kāi)機(jī)代碼,請(qǐng)嘗試讀懂鴻蒙內(nèi)核開(kāi)機(jī)代碼,后續(xù)講詳細(xì)說(shuō)明每行代碼的用處.

開(kāi)機(jī)代碼

    reset_vector:   //開(kāi)機(jī)代碼
    /* clear register TPIDRPRW */
    mov     r0, #0                  @r0 = 0
    mcr     p15, 0, r0, c13, c0, 4  @c0,c13 = 0, C13為進(jìn)程標(biāo)識(shí)符 含義見(jiàn) ARM720T.PDF 第64頁(yè)
    /* do some early cpu setup: i/d cache disable, mmu disabled */ @禁用MMU, i/d緩存
    mrc     p15, 0, r0, c1, c0, 0   @r0 = c1 ,c1寄存器詳細(xì)解釋見(jiàn)第64頁(yè)
    bic     r0, #(1<<12)            @位清除指令,清除r0的第11位
    bic     r0, #(1<<2 | 1<<0)      @清除第0和2位 ,禁止 MMU和緩存 0位:MMU enable/disable 2位:Cache enable/disable
    mcr     p15, 0, r0, c1, c0, 0   @c1=r0 

    /* r11: delta of physical address and virtual address */@物理地址和虛擬地址的增量
    adr     r11, pa_va_offset @將基于PC相對(duì)偏移的地址pa_va_offset值讀取到寄存器R11中
    ldr     r0, [r11]         @將R11的值給r0
    sub     r11, r11, r0      @r11 = r11 - r0   

    mrc     p15, 0, r12, c0, c0, 5              /* r12: get cpuid */ @獲取CPUID
    and     r12, r12, #MPIDR_CPUID_MASK @r12經(jīng)過(guò)掩碼過(guò)濾
    cmp     r12, #0 @當(dāng)前是否為0號(hào)CPU
    bne     secondary_cpu_init @不是0號(hào)主CPU則調(diào)用secondary_cpu_init

    /* if we need to relocate to proper location or not */
    adr     r4, __exception_handlers            /* r4: base of load address */ @r4獲得加載基地址
    ldr     r5, =SYS_MEM_BASE                   /* r5: base of physical address */@r5獲得物理基地址
    subs    r12, r4, r5                         /* r12: delta of load address and physical address */ @r12=r4-r5 加載地址和物理地址的增量
    beq     reloc_img_to_bottom_done            /* if we load image at the bottom of physical address */

    /* we need to relocate image at the bottom of physical address */
    ldr     r7, =__exception_handlers           /* r7: base of linked address (or vm address) */
    ldr     r6, =__bss_start                    /* r6: end of linked address (or vm address) */
    sub     r6, r7                              /* r6: delta of linked address (or vm address) */
    add     r6, r4                              /* r6: end of load address */

異常的優(yōu)先級(jí)

當(dāng)同時(shí)出現(xiàn)多個(gè)異常時(shí),該響應(yīng)哪一個(gè)呢?這涉及到了異常的優(yōu)先級(jí),順序如下

  • 1.Reset (highest priority).
  • 2.Data Abort.
  • 3.FIQ.
  • 4.IRQ.
  • 5.Prefetch Abort.
  • 6.Undefined Instruction, SWI (lowest priority).

可以看出swi的優(yōu)先級(jí)最低,swi就是軟中斷,系統(tǒng)調(diào)用就是通過(guò)它來(lái)實(shí)現(xiàn)的.

3.異常模式怎么切換?

寫(xiě)應(yīng)用程序經(jīng)常會(huì)用到狀態(tài),來(lái)記錄各種分支邏輯,傳遞參數(shù).這么多異常模式,相互切換,中間肯定會(huì)有很多的狀態(tài)需要保存.比如:如何能知道當(dāng)前運(yùn)行在哪種模式下?怎么查?去哪里查呢?
答案是: CPSR(一個(gè)) 和 SPSR(5個(gè))
這些寄存器:

  • 保存有關(guān)最近執(zhí)行的ALU操作的信息
  • 控制中斷的啟用和禁用
  • 設(shè)置處理器操作模式

CPSR 寄存器

CPSR(current program status register)當(dāng)前程序的狀態(tài)寄存器
CPSR有4個(gè)8位區(qū)域:標(biāo)志域(F)、狀態(tài)域(S)、擴(kuò)展域(X)、控制域(C)
32 位的程序狀態(tài)寄存器可分為4 個(gè)域:

    1. 位[31:24]為條件標(biāo)志位域,用f 表示;
    1. 位[23:16]為狀態(tài)位域,用s 表示;
    1. 位[15:8]為擴(kuò)展位域,用x 表示;
    1. 位[7:0]為控制位域,用c 表示;

CPSR和其他寄存器不一樣,其他寄存器是用來(lái)存放數(shù)據(jù)的,都是整個(gè)寄存器具有一個(gè)含義.
而CPSR寄存器是按位起作用的,也就是說(shuō),它的每一位都有專門(mén)的含義,記錄特定的信息.

CPSR的低8位(包括I、F、T和M[4:0])稱為控制位,程序無(wú)法修改,
除非CPU運(yùn)行于特權(quán)模式下,程序才能修改控制位

N、Z、C、V均為條件碼標(biāo)志位。它們的內(nèi)容可被算術(shù)或邏輯運(yùn)算的結(jié)果所改變,
并且可以決定某條指令是否被執(zhí)行!意義重大!

  • CPSR的第31位是 N,符號(hào)標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為負(fù).
    如果為負(fù) N = 1,如果是非負(fù)數(shù) N = 0.
  • CPSR的第30位是Z,0標(biāo)志位。它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為0.
    如果結(jié)果為0.那么Z = 1.如果結(jié)果不為0,那么Z = 0.
  • CPSR的第29位是C,進(jìn)位標(biāo)志位(Carry)。一般情況下,進(jìn)行無(wú)符號(hào)數(shù)的運(yùn)算。
    加法運(yùn)算:當(dāng)運(yùn)算結(jié)果產(chǎn)生了進(jìn)位時(shí)(無(wú)符號(hào)數(shù)溢出),C=1,否則C=0。
    減法運(yùn)算(包括CMP):當(dāng)運(yùn)算時(shí)產(chǎn)生了借位時(shí)(無(wú)符號(hào)數(shù)溢出),C=0,否則C=1。
  • CPSR的第28位是V,溢出標(biāo)志位(Overflow)。在進(jìn)行有符號(hào)數(shù)運(yùn)算的時(shí)候,
    如果超過(guò)了機(jī)器所能標(biāo)識(shí)的范圍,稱為溢出。

MSR{條件} 程序狀態(tài)寄存器(CPSR 或SPSR)_<域>,操作數(shù)
MSR 指令用于將操作數(shù)的內(nèi)容傳送到程序狀態(tài)寄存器的特定域中
示例如下:

    MSR CPSR,R0   @傳送R0 的內(nèi)容到CPSR
    MSR SPSR,R0   @傳送R0 的內(nèi)容到SPSR
    MSR CPSR_c,R0 @傳送R0 的內(nèi)容到CPSR,但僅僅修改CPSR中的控制位域

MRS{條件} 通用寄存器,程序狀態(tài)寄存器(CPSR 或SPSR)
MRS 指令用于將程序狀態(tài)寄存器的內(nèi)容傳送到通用寄存器中。該指令一般用在以下兩種情況:

  1. 當(dāng)需要改變程序狀態(tài)寄存器的內(nèi)容時(shí),可用MRS 將程序狀態(tài)寄存器的內(nèi)容讀入通用寄存器,修改后再寫(xiě)回程序狀態(tài)寄存器。
  2. 當(dāng)在異常處理或進(jìn)程切換時(shí),需要保存程序狀態(tài)寄存器的值,可先用該指令讀出程序狀態(tài)寄存器的值,然后保存。
    示例如下:
MRS R0,CPSR   @傳送CPSR 的內(nèi)容到R0
MRS R0,SPSR   @傳送SPSR 的內(nèi)容到R0
               @MRS指令是唯一可以直接讀取CPSR和SPSR寄存器的指令

SPSR 寄存器

SPSR(saved program status register)程序狀態(tài)保存寄存器.五種異常模式下一個(gè)狀態(tài)寄存器SPSR,用于保存CPSR的狀態(tài),以便異常返回后恢復(fù)異常發(fā)生時(shí)的工作狀態(tài)。

  • 1、SPSR 為 CPSR 中斷時(shí)刻的副本,退出中斷后,將SPSR中數(shù)據(jù)恢復(fù)到CPSR中。
  • 2、用戶模式和系統(tǒng)模式下SPSR不可用,所以SPSR寄存器只有5個(gè)

寫(xiě)在最后

  • 如果你覺(jué)得這篇內(nèi)容對(duì)你還蠻有幫助,我想邀請(qǐng)你幫我三個(gè)小忙:
  • 點(diǎn)贊,轉(zhuǎn)發(fā),有你們的 『點(diǎn)贊和評(píng)論』,才是我創(chuàng)造的動(dòng)力。
  • 關(guān)注小編,同時(shí)可以期待后續(xù)文章ing??,不定期分享原創(chuàng)知識(shí)。
  • 想要獲取更多完整鴻蒙最新學(xué)習(xí)知識(shí)點(diǎn),請(qǐng)移步前往小編:https://gitee.com/MNxiaona/733GH/blob/master/jianshu
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,640評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,957評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,011評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,183評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評(píng)論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,251評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,588評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容