head.s 汇编代码 调试

 

arch/arm/kernel/setup.c

 

static __maybe_unused unsigned long get_cpsr( void ) 
{                                  
    unsigned long reg_var;    

    //mrs r0, cpsr
    asm volatile("mrs %0, cpsr" :"=r"(reg_var): :);               
    return reg_var;                    
}    


__maybe_unused unsigned long get_spsr( void ) 
{                                  
    unsigned long reg_var;    
    //mrs r0, cpsr
    asm volatile("mrs %0, spsr" :"=r"(reg_var): :);               
    return reg_var;                    
}    

static __maybe_unused unsigned long  get_pc( void ) 
{                                  
    unsigned long pc_var1;                                
    asm volatile("mov %0, r15" :"=r"(pc_var1): :);               
    return pc_var1;                    
}         

static __maybe_unused unsigned long get_lr( void ) 
{                                  
    unsigned long reg_var;    
    asm volatile("mov %0, lr" :"=r"(reg_var): :);               
    return reg_var;                    
}  

static __maybe_unused ulong get_sp(void)
{
    ulong ret;

    asm("mov %0, sp" : "=r"(ret) : );
    return ret;
}


static __maybe_unused ulong get_ip(void)
{
    ulong ret;

    asm("mov %0, ip" : "=r"(ret) : );
    return ret;
}

static __maybe_unused ulong get_r12(void)
{
    ulong ret;

    asm("mov %0, r12" : "=r"(ret) : );
    return ret;
}

static __maybe_unused ulong get_fp(void)
{
    ulong ret;

    asm("mov %0, fp" : "=r"(ret) : );
    return ret;
}

static __maybe_unused ulong get_r11(void)
{
    ulong ret;

    asm("mov %0, r11" : "=r"(ret) : );
    return ret;
}


void __init early_print_debug_info2(const char *str, ...)
{
    extern void printascii(const char *);
    char buf[256];
    va_list ap;
    va_start(ap, str);
    vsnprintf(buf, sizeof(buf), str, ap);
    va_end(ap);
    
    printascii(buf);
}


//Role in the procedure call standard
//r15 PC The Program Counter.
//r14 LR The Link Register.
//r13 SP The Stack Pointer.
//r12 IP The Intra-Procedure-call scratch register. (可简单的认为暂存SP)
 
//实际上,还有一个r11是optional的,被称为FP,即frame pointer。


//dump_stack();

void __init early_print_debug_info(const char *str, ...)
{
    extern void printascii(const char *);
    

    __maybe_unused struct pt_regs *regs;

    unsigned long reg;
    unsigned long *reg_p;
    int i;
    char buf[256];
    va_list ap;
    va_start(ap, str);
    vsnprintf(buf, sizeof(buf), str, ap);
    va_end(ap);


    printascii(buf);
    printascii("hahaha:\n");


    
    reg = get_sp();
    early_print_debug_info2("sp = %lx\n", reg);

    reg = get_pc();
    early_print_debug_info2("pc = %lx\n", reg);

    reg = get_ip();
    early_print_debug_info2("ip = %lx\n", reg);

    reg = get_r12();
    early_print_debug_info2("r12 = %lx\n", reg);


    
    reg = get_fp();
    early_print_debug_info2("fp = %lx\n", reg);
    
    reg = get_r11();
    early_print_debug_info2("r11 = %lx\n", reg);


    reg_p = (unsigned long *)reg;

    for( i=0x00; i<5+13+1; i++ ){
         early_print_debug_info2("reg[%08x] = 0x%lx\n", i, reg_p[i] );
    }

    regs = (struct pt_regs *)reg_p;

    early_print_debug_info2("reg_p = 0x%p\n", reg_p );

    //early_print_debug_info2("&regs->ARM_pc = 0x%x\n", &regs->ARM_pc );
    //early_print_debug_info2("&regs->ARM_r0 = 0x%x\n", &regs->ARM_r0 );


    


}

#if 0

for test call c func: 
hahaha:
sp = bacc0e40
pc = 40e04358
ip = bacc0cb8
r12 = bacc0cb8
fp = bacc0f64
r11 = bacc0f64
reg[00000000] = 0x40e0430c  PC
reg[00000001] = 0x40008094  R0
reg[00000002] = 0xffffffff  R1
reg[00000003] = 0x44000000  R2
reg[00000004] = 0x400080b4  R3

reg[00000005] = 0x0         R0
reg[00000006] = 0xffffffff  R1
reg[00000007] = 0x44000000  R2
reg[00000008] = 0x400080b4  R3
reg[00000009] = 0x80000000  R4
reg[0000000a] = 0x409a0288  R5
reg[0000000b] = 0x409a03f4  R6
reg[0000000c] = 0xdfe278    R7
reg[0000000d] = 0x40000000  R8
reg[0000000e] = 0x410fc075  R9
reg[0000000f] = 0x409a0288  R10
reg[00000010] = 0x0         R11 
reg[00000011] = 0x0         R12
reg[00000012] = 0x40008048  LR_CALL_IN

#endif

//sub    r4, r3, r4            @ (PHYS_OFFSET - PAGE_OFFSET)  0x400080e0 - 0xc00080e0 = 0x80000000
//add    r8, r8, r4            @ PHYS_OFFSET   0xc0000000 + 0x80000000 = 0x40000000


 

 

arch/arm/kernel/head.S

#ifndef CONFIG_XIP_KERNEL
    adr    r3, 2f
    ldmia    r3, {r4, r8}
    sub    r4, r3, r4            @ (PHYS_OFFSET - PAGE_OFFSET)  0x400080e0 - 0xc00080e0 = 0x80000000
    add    r8, r8, r4            @ PHYS_OFFSET   0xc0000000 + 0x80000000 = 0x40000000

    @mov    r12, r3        
    @bl dump_reg_n
    @bl dump_new_line

    stmfd    sp!, {r0 - r12, lr}
    adr    r0, head_str_entry1
    bl early_print_debug_info
    ldmfd    sp!, {r0 - r12, lr}
    

    
#else
    //ldr    r8, =PLAT_PHYS_OFFSET        @ always constant in this case
#endif
......

head_str_entry1:    .asciz    "\n for test call c func: \n"
ENDPROC(stext)

 

early_print_debug_info 函数的反汇编:

.init.text:00000614                 MOV             R12, SP
.init.text:00000618                 STMFD           SP!, {R0-R3}
.init.text:0000061C                 STMFD           SP!, {R4,R11,R12,LR,PC}
.init.text:00000620                 SUB             R11, R12, #0x14

R11在函数中不会改变 就是这个值   r11->PC

由R11的值可以反推堆栈中的内容

但是看有的函数 是 -4

get_spsr
.text:00000330
.text:00000330 var_10          = -0x10
.text:00000330
.text:00000330                 MOV             R12, SP
.text:00000334                 STMFD           SP!, {R11,R12,LR,PC}
.text:00000338                 SUB             R11, R12, #4
.text:0000033C                 STR             LR, [SP,#0xC+var_10]!
.text:00000340
.text:00000340 loc_340                                 ; DATA XREF: __mcount_loc:00002794o
.text:00000340                 BL              __gnu_mcount_nc
.text:00000344                 MRS             R0, SPSR
.text:00000348                 LDMFD           SP, {R11,SP,PC}
.text:00000348 ; End of function get_spsr

这种情况 R11指向的还是PC,但是R0,R1,R2,R3没有入堆栈

 


.init.text:00000624                 SUB             SP, SP, #0x10C
.init.text:00000628                 MOV             R1, #0x100 ; maxlen
.init.text:0000062C                 LDR             R4, =__stack_chk_guard

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值