Skip to content

2012年 408 计算机组成原理 第 15 题

计算机组成原理2012年选择题2分

题目

某计算机存储器按字节编址,采用小端方式存放数据。假定编译器规定 int 型和 short 型长度分别为 32 位和 16 位,并且数据按边界对齐存储。某 C 语言程序段如下:

c
struct {
    int a;
    char b;
    short c;
} record;

record.a = 273;

若 record 变量的首地址为 0xC008,则地址 0xC008 中存放的内容及 record.c 的地址分别为( )。

错因

A

两处错都出现了

  1. 把 273 = 0x00000111 用大端方式存放——大端把高字节放低地址,所以 0xC008 处是 0x00、0xC00B 处才是 0x11。题目明写"小端",方向正好相反
  2. 忽略了边界对齐——把 short c 紧贴 char b 后面放,c 的地址 = 0xC00D。但 short 要按 2 字节边界对齐,必须填 1 字节空位,c 的地址应为 0xC00E。

B

把 0xC008 处的内容算成 0x00 —— 同 A 的"大端方向"错。c 的地址 0xC00E 倒是对的(说明意识到了对齐,只是字节序记反了)。

C

字节序对了(小端 → 0xC008 处放 0x11),但 c 的地址错算成 0xC00D —— 漏了 1 字节填充。char b 占 1 字节(在 0xC00C),剩下 0xC00D 是为对齐而填的空位,short c 必须从 0xC00E 开始。

总解析

第一步:算出 a = 273 的 32 位机器数

写成 4 字节十六进制:

第二步:按小端方式把 a 摊到内存

小端规则:低字节放低地址,按字节从右到左依次填入升序地址。

地址内容
0xC008(最低)0x11
0xC0090x01
0xC00A0x00
0xC00B(最高)0x00

所以 0xC008 处存的就是 0x11。

第三步:算出 record.c 的地址(边界对齐)

按"自然对齐"规则——类型大小为 N 字节的成员,地址必须是 N 的倍数

成员类型大小对齐要求实际占用区间
aint4 字节4 字节对齐0xC008 ~ 0xC00B
bchar1 字节1 字节对齐0xC00C
padding1 字节0xC00D(填充 1 字节让 c 对齐)
cshort2 字节2 字节对齐0xC00E ~ 0xC00F

为什么要 1 字节 padding?b 紧接 a 后从 0xC00C 开始(OK,char 无对齐要求);接下来 short c 需要 2 字节边界,0xC00D 不是 2 的倍数,必须跳到下一个 2 的倍数 = 0xC00E

第四步:拼答案

  • 0xC008 处内容 = 0x11
  • record.c 的地址 = 0xC00E

最终答案是 D(0x11、0xC00E)

两个判定要点速记

  1. 小端 = 低字节存低地址("小尾巴 little-endian = 小数字(低位)放小地址")
    • 大端反之,低位在高地址
    • x86 / x64 是小端;网络字节序(TCP/IP)是大端
  2. 自然对齐 = 类型大小是几就按几对齐(int 按 4,short 按 2,char 按 1);compiler 在不对齐位置自动插 padding

编者注(格式修复):原题面在 record.a = 273; 后断开,缺"若 record 变量的首地址为 0xC008,则地址 0xC008 中存放的内容及 record.c 的地址分别为( )"这句问题文字(OCR/抄写漏行),已按真题原文补回(首地址 0xC008 由四个选项的 c 地址倒推唯一确定)。

最后更新:

⚠️ 这道题暂未配可视化,欢迎在 CodeBrick 反馈区告诉我们你想看哪道题