powerpc汇编指令分析

1基础知识

ØVxworks shell命令

i

b&bh&bdall

c

ti&tt

cret:执行到子函数返回,返回后的结果可以在r3寄存器里看到。先b断住子函数,然后用cret taskid,查看r3就知道了子函数返回的结果。

e l1_print_bit_number,2,0,printf,”abcd\n”:当执行到l1_print_bit_number函数时,执行printf(“abcd\n”)。

b l1_print_bit_number,0,2,0:当执行l1_print_bit_number函数2次后,即第3次断点生效。

Ø基本指令

stwu        r1,-48(r1) :1) [r1-48]<-r1;                2) r1= r1-48

sth                r0,8(r31):                lower 16bits of r0, save to [r31+8]

lwz r9,8(r31):                load [r31+8]'s 32bits to r9

mr  r31,   r1:                r1->r31  migrate register

mtlr                r0:                migrate r0 to lr register

Ø条件指令

CRCondition Register一共32位,从低位到高位被分成 CR0-CR7八段,每段四位。每个四位的CRn从低到高分别是:LT(小于标志)、GT(大于)、EQ(等于)和SO(溢出)比较指令或条件跳转指令均可指明具体操作哪个 CRn,由此可以同时判断多个条件。整数计算默认更改CR0,浮点数计算默认更改CR1

指令的语法格式:

bcctr BO, BI(LK=0)

bcctrl BO, BI(LK=1)

BO字段常用操作码:
BO=00100 如果条件成立(CR[BI]==0)则发生跳转
BO=01100 如果条件不成立(CR[BI]==1)则发生跳转
BO=10100 直接跳

如果LK1,则转移指令下一条指令的有效地址存放到连接寄存器。

如果减量计数器(BO[2]=0),指令格式无效,则转移到目标地址。

bcctrl      0x14,0:1)跳转到ctr0x15a083c)处。2)lr =(cur pc + 4), 其中0x14 = 0001 0100

2汇编代码

Ø真实环境里的代码分析

-> l l1_print_comment_line,200

                        l1_print_comment_line:

0x9a403c  9421ffd0    stwu        r1,-48(r1)  //                1) [r1-48]<-r1;                2) r1= r1-48

0x9a4040  7c0802a6    mfspr       r0,LR               

0x9a4044  90010034    stw         r0,52(r1)❶ //存储调用者的LR值,后面的处执行 后,r0就是这里存储进去的值。

0x9a4048  93e1002c    stw         r31,44(r1)

0x9a404c  7c3f0b78    or          r31,r1,r1//                r31=r1

0x9a4050  907f0018    stw         r3,24(r31)

0x9a4054  38000000    li          r0,0x0 # 0

0x9a4058  901f0008    stw         r0,8(r31)

0x9a405c  38000000    li          r0,0x0 # 0

0x9a4060  901f0008    stw         r0,8(r31)

0x9a4064  4800002c    b           0x9a4090 # 0x009a4090

0x9a4068  3d200205    lis         r9,0x205 # 517

0x9a406c  38691f60    addi        r3,r9,0x1f60 # 8032

0x9a4070  3d20015a    lis         r9,0x15a # 346

0x9a4074  3929083c    addi        r9,r9,0x83c # 2108

0x9a4078  7d2903a6    mtspr       CTR,r9

0x9a407c  4cc63182    crxor       crb6,crb6,crb6

0x9a4080  4e800421    bcctrl      0x14,0                //1)跳转到ctr(0x15a083c)处。2)lr =(0x9a4080+4) =0x9a4084

0x9a4084  813f0008    lwz         r9,8(r31)

0x9a4088  38090001    addi        r0,r9,0x1 # 1

0x9a408c  901f0008    stw         r0,8(r31)

0x9a4090  801f0008    lwz         r0,8(r31)

0x9a4094  813f0018    lwz         r9,24(r31)

0x9a4098  7f804800    cmp         crf7,0,r0,r9

0x9a409c  419cffcc    bc          0xc,28, 0x9a4068 # 0x009a4068

0x9a40a0  3d200205    lis         r9,0x205 # 517

0x9a40a4  38691f64    addi        r3,r9,0x1f64 # 8036

0x9a40a8  3d20015a    lis         r9,0x15a # 346

0x9a40ac  3929083c    addi        r9,r9,0x83c # 2108

0x9a40b0  7d2903a6    mtspr       CTR,r9

0x9a40b4  4cc63182    crxor       crb6,crb6,crb6

0x9a40b8  4e800421    bcctrl      0x14,0//1)跳转到ctr(0x15a083c)处。2)lr =(0x9a40b8+4) =0x9a40bc

0x9a40bc  81610000    lwz         r11,0(r1) ❷

0x9a40c0  800b0004    lwz         r0,4(r11)                //r0 =调用者调用地方的下一条指令地址,就是处存储的值。

0x9a40c4  7c0803a6    mtspr       LR,r0                //1) lr =r0

0x9a40c8  83ebfffc    lwz         r31,-4(r11)

0x9a40cc  7d615b78    or          r1,r11,r11

0x9a40d0  4e800020    blr                                //返回到 lr 寄存器里的地址

                        l1_print_spaces:

0x9a40d4  9421ffd0    stwu        r1,-48(r1)

0x9a40d8  7c0802a6    mfspr       r0,LR

0x9a40dc  90010034    stw         r0,52(r1)

0x9a40e0  93e1002c    stw         r31,44(r1)

0x9a40e4  7c3f0b78    or          r31,r1,r1

0x9a40e8  907f0018    stw         r3,24(r31)

0x9a40ec  38000000    li          r0,0x0 # 0

0x9a40f0  901f0008    stw         r0,8(r31)

0x9a40f4  38000000    li          r0,0x0 # 0

0x9a40f8  901f0008    stw         r0,8(r31)

0x9a40fc  4800002c    b           0x9a4128 # 0x009a4128

0x9a4100  3d200205    lis         r9,0x205 # 517

0x9a4104  38691f68    addi        r3,r9,0x1f68 # 8040

0x9a4108  3d20015a    lis         r9,0x15a # 346

0x9a410c  3929083c    addi        r9,r9,0x83c # 2108

0x9a4110  7d2903a6    mtspr       CTR,r9

0x9a4114  4cc63182    crxor       crb6,crb6,crb6

0x9a4118  4e800421    bcctrl      0x14,0

0x9a411c  813f0008    lwz         r9,8(r31)

0x9a4120  38090001    addi        r0,r9,0x1 # 1

0x9a4124  901f0008    stw         r0,8(r31)

0x9a4128  801f0008    lwz         r0,8(r31)

0x9a412c  813f0018    lwz         r9,24(r31)

0x9a4130  7f804800    cmp         crf7,0,r0,r9

0x9a4134  419cffcc    bc          0xc,28, 0x9a4100 # 0x009a4100

0x9a4138  81610000    lwz         r11,0(r1)

0x9a413c  800b0004    lwz         r0,4(r11)

0x9a4140  7c0803a6    mtspr       LR,r0

0x9a4144  83ebfffc    lwz         r31,-4(r11)

0x9a4148  7d615b78    or          r1,r11,r11

0x9a414c  4e800020    blr

                        l1_print_bit_number:

0x9a4150  9421ffd0    stwu        r1,-48(r1)

0x9a4154  7c0802a6    mfspr       r0,LR

0x9a4158  90010034    stw         r0,52(r1)

0x9a415c  93e1002c    stw         r31,44(r1)

0x9a4160  7c3f0b78    or          r31,r1,r1

0x9a4164  907f0018    stw         r3,24(r31)

0x9a4168  909f001c    stw         r4,28(r31)

0x9a416c  38000000    li          r0,0x0 # 0

0x9a4170  901f0008    stw         r0,8(r31)

0x9a4174  801f0018    lwz         r0,24(r31)

0x9a4178  2f800000    cmpi        crf7,0,r0,0x0 # 0

0x9a417c  409d007c    bc          0x4,29, 0x9a41f8 # 0x009a41f8

0x9a4180  813f0018    lwz         r9,24(r31)

0x9a4184 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 我对于这个具体问题没有相关知识.但是我可以告诉你32位PowerPC架构中sys_fork的大体实现流程。 sys_fork是Linux内核中用于实现进程创建的系统调用。它会创建一个新的进程,该进程是调用进程的副本。新进程的所有资源都是从父进程复制而来的。在PowerPC架构中,sys_fork的实现可能包括使用内联汇编来实现低级的进程复制和管理操作。 ### 回答2: sys_fork是一个系统调用函数,实现在32位PowerPC架构的操作系统中创建一个子进程。下面是sys_fork函数的内联汇编代码: ``` .globl sys_fork sys_fork: mflr r0 ; 将链接寄存器的内容保存到r0寄存器 stwu r1, -STACK_SIZE(r1) ; 保存状态寄存器到栈中 li r3, __NR_fork ; 设置系统调用号(__NR_fork是fork的系统调用号) sc ; 调用操作系统的系统调用 cmpwi r3, 0 ; 检查系统调用返回值是否为0 bne error_exit ; 若不为0,表示fork系统调用失败,则跳转到error_exit标签 lwzu r1, STACK_SIZE(r1) ; 恢复状态寄存器的值 mtlr r0 ; 将r0寄存器的值恢复到链接寄存器 blr ; 返回调用函数 error_exit: neg r3, r3 ; 将返回值取反 lwzu r1, STACK_SIZE(r1) ; 恢复状态寄存器的值 li r0, -1 ; 设置返回值为-1 stw r0, 0(r3) ; 将返回值存储到r3寄存器指向的地址中 mtlr r0 ; 将r0寄存器的值恢复到链接寄存器 blr ; 返回调用函数 ``` 以上是一个简单的32位PowerPC架构的sys_fork函数的内联汇编代码。它保存链接寄存器的值到r0寄存器,并将状态寄存器保存到栈中。然后使用系统调用号__NR_fork调用操作系统的系统调用。若系统调用返回值为0,则恢复状态寄存器的值,并返回到调用函数。若系统调用返回值不为0,则将返回值取反并存储到r3寄存器指向的地址中,并返回到调用函数。若fork系统调用失败,则设置返回值为-1,再返回到调用函数。 ### 回答3: sys_fork 是一个用来实现在 32 位 PowerPC 架构上进行进程分叉的系统调用。在内联汇编代码中,我们可以使用一些特殊的指令来实现这一功能。 在 PowerPC 架构上,通常会使用 trap 指令来实现系统调用,该指令将软件中断传递给操作系统。对于 sys_fork 调用,我们可以使用三个参数来传递给操作系统:r3 用于指向调用父进程的程序计数器的指针,r4 用于将父进程的保存状态传递给操作系统,r5 用于将子进程的保存状态传递给操作系统。 以下是伪代码展示了如何使用内联汇编来实现 sys_fork: ``` #define __NR_fork 2 int sys_fork(void) { int ret; asm volatile( "li 0, %[syscall_number]\n" // 将系统调用号存储在寄存器 0 中 "sc\n" // 执行系统调用 "mr %[result], 3\n" // 将系统调用结果保存在变量 "result" 中 : [result] "=a"(ret) // 输出参数 : [syscall_number] "i"(__NR_fork) // 输入参数 : "memory", "r0" // 使用的内存和寄存器 ); return ret; } ``` 在这段代码中,我们首先使用 li 指令将系统调用号存储在寄存器 0 中。然后,使用 sc 指令执行系统调用。接下来,使用 mr 指令将系统调用结果保存在变量 "result" 中。最后,返回系统调用的结果。 需要注意的是,这只是一种可能的实现方式,具体实现可能会根据不同的操作系统和编译器有所不同。在实际的代码中,可能还会涉及到其他的处理步骤,如保存寄存器和处理错误等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值