深入理解计算机操作系统第三章家庭作业

3.58

y=y-z;
x=x*y;
return x ^ (y<<63>>63);

3.59

无符号64位,ux 和 uy
有符号64位,x 和 y
设 x 和 ux 具有相同的位,y 和 uy 具有相同的位,
ux = x + Sx*2^64
ux = y + Sy*2^64
ux * uy = (x + Sx * 2^64) * (y + Sy * 2^64)
ux * uy = x*y + (Sx*y + Sy*x)*2^64 + Sx*Sy*2^128
ux * uy = x*y + (Sx*y + Sy*x)*2^64
x*y = ux * uy - (Sx*y + Sy*x)*2^64


movq    %rdx, %rax         rax 存有 y
cqto                       rdx 存有 -Sy (存的位要么是全 1,要么全 0)
movq    %rsi, %rcx         rcx 存有 x
sarq    $63, %rcx          rcx 存有 -Sx
imulq   %rax, %rcx         rcx 存有 -Sx * y (注意,imul 不分有符号乘法还是无符号乘法,只保留低 64 位,这边不可能溢出,因为 Sx 要么 1 要么 0)
imulq   %rsi, %rdx         rdx 存有 -Sy * x
addq    %rdx, %rcx         rcx 存有 -Sx*y + -Sy*x
mulq    %rsi               rax 存有 ux * uy 低 64 位, rdx 存有积的高 64 位
addq    %rcx, %rdx         rdx 存有 (ux * uy)/2^64 - (Sx*y + Sy*x)
movq    %rax, (%rdi)       低 64 位
movq    %rdx, 8(%rdi)      高 64 位
ret

3.60

long loop(long x, int n) {
    long result = 0;
    long mask;
    for (mask = 1; mask != 0; mask = mask << n) {
        result |= x & mask;
    }
    return result;
}

3.61

long cread(long *xp) {
    return (xp ? *xp : 0);
}

long cread_alt(long *xp) {
    return (!xp ? 0 : *xp);
}

// 现在的编译器比较智能,已经不会像书中一样编译这段代码了。

3.62

typedef enum {
    MODE_A, MODE_B, MODE_C, MODE_D, MODE_E
} mode_t;

long switch3(long *p1, long *p2, mode_t action) {
    long result = 0;
    switch (action) {
        case MODE_A:
            result = *p2;
            *p2 = *p1;
            break;
        case MODE_B:
            result = *p1 + *p2;
            *p1 = result;
            break;
        case MODE_C:
            *p1 = 59;
            result = *p2;
            break;
        case MODE_D:
            *p1 = *p2;
        case MODE_E:
            result = 27;
            break;
        default:
            result = 12;
            break;
    }
    return result;
}

3.63

long switch_prob(long x, long n) {
    long result = x;
    switch (n) {

        case 60:
        case 62:
            result = 8 * x;
            break;
        case 63:
            result = x >> 3;
            break;
        case 64:
            result = x * 15;
            x = result;
        case 65:
            x = x * x;
        case 61:
        default:
            result = 75 + x;
    }
    return result;
}

3.64

&D[i][j][k] = D + (S*T*i + T*j + k) * L

R = 7
S = 5
T = 13

3.65

A.
&A[i][j] in %rdx

B.
&A[j][i] in %rax

C.
M = 15

3.66

NR(n) == 3*n
NC(n) == n*4 + 1

3.67

A.

104  +------------------+
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
 64  +------------------+ <-- %rdi
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
 32  +------------------+
     |         z        |
 24  +------------------+
     |        &z        |
 16  +------------------+
     |         y        |
  8  +------------------+
     |         x        |
  0  +------------------+ <-- %rsp

B.
eval 传了一个新地址给 process ,新地址是 %rsp+64

C.
process 通过栈指针来访问 s,而不是通过 %rdi

D.
process 将参数 %rsp+64 设置为起点,将 r 的成员设置进来,并在最后返回 r 的指针。

E.

104  +------------------+
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
     |                  |
 88  +------------------+
     |        z         |
 80  +------------------+
     |        x         |
 72  +------------------+
     |        y         |
 64  +------------------+ <-- %rdi(eval pass in)
     |                  |  \
     |                  |   -- %rax(process pass out)
     |                  |
     |                  |
     |                  |
     |                  |
 32  +------------------+
     |         z        |
 24  +------------------+
     |        &z        |
 16  +------------------+
     |         y        |
  8  +------------------+
     |         x        |
  0  +------------------+ <-- %rsp in eval
     |                  |
 -8  +------------------+ <-- %rsp in process

F.
调用者设置一个地址给被调用者作为起点存储成员数据,被调用者最后返回这个地址。

3.68

提示:考虑对齐产生的空隙,所以最后产生的一个范围
4 < B <= 8
6 < A <= 10
44 < A*B <= 46

得:A=9, B=5

3.69

A.
CNT = 7

B.
typedef struct {
  long idx,
  long x[4]
} a_struct;

3.70

A.
0 8 0 8

B.
16

C.
void proc(union ele *up) {
    up->e2.x = *(up->e2.next->e1.p) - up->e2.next->e1.y;
}

3.71

#include <stdio.h>
#include <assert.h>

#define BUF_SIZE 12

void good_echo(void) {
    char buf[BUF_SIZE];
    while (1) {
        /* function fgets is interesting */
        char *p = fgets(buf, BUF_SIZE, stdin);
        if (p == NULL) {
            break;
        }
        printf("%s", p);
    }
    return;
}

int main(int argc, char *argv[]) {
    good_echo();
    return 0;
}

3.72

A.
n 是奇数时:
s_2 = s_1 - (n * 8 + 24)
n 是偶数时:
s_2 = s_1 - (n * 8 + 16) s

B.
p 是 16 位的倍数

C.

-- e1 n s1
最小 1 偶数 n%16==1
最大 24 奇数 n%16==0

D.
p 按 16 字节对齐,
s2 十六的倍数,并且至少有 8*n 的空间。

3.73

#include <stdio.h>
#include <assert.h>

typedef enum {
    NEG, ZERO, POS, OTHER
} range_t;

range_t find_range(float x) {
    __asm__(
    "vxorps %xmm1, %xmm1, %xmm1\n\t"
    "vucomiss %xmm1, %xmm0\n\t"
    "jp .P\n\t"
    "ja .A\n\t"
    "jb .B\n\t"
    "je .E\n\t"
    ".A:\n\t"
    "movl $2, %eax\n\t"
    "ret\n\t"
    ".B:\n\t"
    "movl $0, %eax\n\t"
    "ret\n\t"
    ".E:\n\t"
    "movl $1, %eax\n\t"
    "ret\n\t"
    ".P:\n\t"
    "movl $3, %eax\n\t"
    "ret\n\t"
    );
}

int main(int argc, char *argv[]) {
    range_t n = NEG, z = ZERO, p = POS, o = OTHER;
    assert(o == find_range(0.0 / 0.0));
    assert(n == find_range(-2.3));
    assert(z == find_range(0.0));
    assert(p == find_range(3.33));
    return 0;
}

3.74

#include <stdio.h>
#include <assert.h>

typedef enum {
    NEG, ZERO, POS, OTHER
} range_t;

range_t find_range(float x) {
    __asm__(
    "vxorps %xmm1, %xmm1, %xmm1\n\t"
    "movq $1, %rax\n\t"
    "movq $2, %r8\n\t"
    "movq $0, %r9\n\t"
    "movq $3, %r10\n\t"
    "vucomiss %xmm1, %xmm0\n\t"
    "cmovaq %r8, %rax\n\t"
    "cmovbq %r9, %rax\n\t"
    "cmovpq %r10, %rax\n\t"
    );
}

int main(int argc, char *argv[]) {
    range_t n = NEG, z = ZERO, p = POS, o = OTHER;
    assert(o == find_range(0.0 / 0.0));
    assert(n == find_range(-2.3));
    assert(z == find_range(0.0));
    assert(p == find_range(3.33));
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352