code:1242 ~ 1281 - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

1242 /* ------------------------- */

1243 .globl _copyin, _copyout

copyin
  • 用户态地址空间 读入数据
  • 共传入3个参数,设为src dst count
    • src : 用户态地址空间 数据源地址
    • dst : 核心态地址空间 目标地址
    • count : 读入数据长度(字节)
  • 返回值
    • 若成功,返回0
    • 否则,返回-1
  • 进入函数时,堆栈状态如下

1244 _copyin:

1245     jsr pc,copsu

  • 跳转到 子程序 1264
    • src → R0
    • dst → R1
    • count/2 → R2
1246 1:

1247     mfpi (r0)+

1248     mov (sp)+,(r1)+

1249     sob r2,1b

  • 1247 - 1249 构成循环
  • 不断 从 用户态地址空间 数据源地址 读出数据到 核心态地址空间 目标地址
  • 共读 数据长度为 count/2 个字
1250     br 2f
  • 跳转到 1258
1251
copyout
  • 用户态地址空间 写入数据
  • 共传入3个参数,设为src dst count
    • src : 用户态地址空间 数据目标地址
    • dst : 核心态地址空间 数据源地址
    • count : 写入数据长度(字节)
  • 返回值
    • 若成功,返回0
    • 否则,返回-1
  • 进入函数时,堆栈状态如下

1252 _copyout:

1253     jsr pc,copsu

  • 跳转到 子程序 1264
    • src → R0
    • dst → R1
    • count/2 → R2
1254 1:

1255     mov (r0)+,-(sp)

1256     mtpi (r1)+

1257     sob r2,1b

  • 1254 - 1257 构成循环
  • 不断 从 核心态地址空间 数据源地址 写入数据到 用户态地址空间 数据目标地址
  • 共写 数据长度为 count/2 个字
1258 2:

1259     mov (sp)+,nofault

1260     mov (sp)+,r2

1261     clr r0

1262     rts pc

  • 从堆栈恢复 nofault 和 r2
  • 返回值 r0 置 0
  • 函数返回
1263

1264 copsu:

1265     mov (sp)+,r0

1266     mov r2,-(sp)

1267     mov nofault,-(sp)

1268     mov r0,-(sp)

  • 1265 - 1268 的作用是调整堆栈结构,调整完堆栈结构如图

  • 压入堆栈的nofault双字是由1267一句完成
1269     mov 10(sp),r0

1270     mov 12(sp),r1

1271     mov 14(sp),r2

1272     asr r2

  • src → R0
  • dst → R1
  • count/2 → R2
1273     mov $1f,nofault
  • 将 1276 子程序 设置为出错处理函数
1274     rts pc

1275

  • 以下 为 1276 子程序,用于出错处理
    • 从堆栈恢复 nofault 和 r2
    • 返回值 r0 置 -1
1276 1:

1277     mov (sp)+,nofault

1278     mov (sp)+,r2

1279     mov $-1,r0

1280     rts pc

1281

Ref

Caller

⚠️ **GitHub.com Fallback** ⚠️