|
文件prf.c
此文件包含以下函数:
printf() panic()
printn() prdev()
putchar() deverror()
它们存在如下的调用关系:
panic deverror
| |
| predev
| |
\ /
printf
|
printn
|
putchar
function printf() 给操作系统提供了一种向系统控制台终端发送消息的方法;直接、不带缓存;
在系统初启、硬件出错、系统突然崩溃时使用.
[code:1]
/*
* Scaled down version of C Library printf.
* Only %s %l %d (==%l) %o are recognized.
* Used to print diasnostic information
* directly on console tty.
* Since it is not interrupt driven,
* all sysytem activities are pretty much
* suppended.
* printf should not be used for chit-chat.
*/
printf(fmt, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc)
/* 只用到了fmt和x1两个参数 */
char fmt[]; /* 这个定义类似于 char *fmt; 不同的是 char fmt[]; 中,fmt[]的值是不可以改变的 */
{
register char *s;
register *adx, c;
adx = &x1; /* x1占用的是栈单元,编译时不能对它求值,所以让adx指向x1 */
loop: /* while(1) { */
while((c = *fmt++) != '%') {
if(c == '\0')
return;
putchar(c);
}
c = *fmt++; /* 判断格式 */
if(c == 'd' || c == 'l' || c == 'o')
printn(*adx, c == 'o'? 8:10);/* 八进制 或 十进制 */
if(c == 's') {
s = *adx;
while(c = *s++)
putchar(c);
}
adx++;
goto loop; /* } */
}
/* ------------------------------ */
[/code:1]
printn() 按照所要求的顺序产生相应数字字符
[code:1]
/*
* Print an unsigned integer in base b
*/
printn(n, b)
{
register a;
if(a = ldiv(n, b))
printn(a, b);
putchar(lrem(n, b) + '0');
}
/* ------------------------------ */
.globl _ldiv
_ldiv
clr r0
mov 2(sp), r1
div 4(sp), r0
rts pc
/* 似乎是对ldiv的定义 */
.globl _lrem
_lrem
clr r0
mov 2(sp), r1
div 4(sp), r0
mov r1, r0
rts pc
/* ------------------------------ */
[/code:1]
因为这个系统是在PDP11计算机上运行的,所以
处理器包含了一组16位的寄存器
r0、r1、r2、r3、r4、r5、r6、r7 是通用寄存器
其中前六个可以作为累加器、地址指针或变址寄存器
一般来说:
r0、r1在表达式求值时用做临时累加器;在函数返回时存放返回值;在函数调用的某些情况下可用来传递实参。
r2、r3和r4在函数执行时可用做局部变量;在函数调用入口处存储这些寄存器的值,在退出时恢复它们的值。
r5用作函数激活记录动态链的链首指针,该动态链存放在当前栈上。r5被成为“环境指针”。
r6(也称sp)用作栈指针
r7(也称pc)程序计数器,即指令地址寄存器。
汇编指令:
adc 将C位的内容加至目的操作数
add 将源操作数加至目的操作数
ash 按移位记数将指定寄存器的内容左移相应次数
ashc 功能与ash相同,但是涉及两个寄存器
asl 所有位左移1位,第0位装入0,第15位装入C
asr 所有位右移1位,第15位保持原值,第0位装入C
beq 等于转移
bge 大于或等于转移
bhi 高于转移
bhis 高于或相同转移
bic 若源操作数的位非0,则将目的操作数中的相应位清0
bis 对源操作数和目的操作数执行或操作,将结果存入目的操作数
bit 对源操作数和目的操作数执行逻辑与操作,设置条件码
ble 大于或等于转移
blo 低于转移
bne 不等于转移
br 转移到.-128和.+127之间的一个单元,.代表当前地址
clc 清除C
clr 目的操作数清0
cmp 比较源操作数和目的操作数。设置条件码
dec 将目的操作数减1
div 存在rn和r(n+1)中的32位二进制补码整数被除以源操作数,商在rn中,余数在r(n+1)中
inc 将目的操作数加1
jmp 跳转到目的操作数
jsr 跳转到子程序
mtpi 从当前栈弹出一个字,将其存入当前地址空间中的指定字节中
mov 将源操作数复制到目的操作数
mfpi 将前地址空间中指定字的值压入当前栈 |
|