目录
Chap. III Registers & Memory Access
summery
仅凭CPU的寄存器是很难完成什么复杂任务的,此时需要内存的访问。
endianness
实际上,就像鸡蛋的问题一样,没有技术上的原因来选择字节顺序规则。
(小端法)字数据的存-取原则:高-高 低-低,即
- 字数据的低位字节存放在低地址内存单元;
- 字数据的高位字节存放在高地址内存单元;
取低地址内存单元地址作为字数据地址
ds
Data Segment 数据段
Attention
- 两个段寄存器之间不能直接传送
Illegal:mov ds, cs
- 不能把常数送到段寄存器。
Illegal:mov ds, 1000H
mov add sub
add & sub
- 指令的操作数不能同时是内存单元
Illegal:add [1], [2]
- 指令的操作数不能是段寄存器0
Illegal:add ds, [2]
stack
summery
The order in which elements come off a stack gives rise to its alternative name, LIFO (last in, first out).
栈顶: 最后入栈的字数据所对应的地址单元
栈底: 固定的一端,栈区最高地址单元的前一个单元
任意时刻,SS(Stack Segment):SP(Stack Pointer) 指向栈顶元素。
栈底元素不记录。
PUSH SP = SP – 2
POP SP = SP + 2
stack overflow and stack underflow
常见程序Runtime Error原因 —— 爆栈和弹空栈。
一种特殊情况:栈长度为0xFFFF,爆栈并不会发生什么,很难察觉到的错误。
所以有了std::stack?
汇编不会主动检查越界行为,所以需要手动检查,手动管理栈空间大小。
所以有了PWN?
CTF见的比较多,ACM就不怎么常见了。
application
- 保护现场(保存进入子程序前的状态,pop顺序与push顺序相反)
- 数据交换(利用LIFO性质,pop顺序与push顺序相同)
‘segment’
人为划分的段,可以重合。
有可能出现一个问题,数据段和代码段有可能是混在一起的,并不安全。
所以说 Segmentation Fault(SIGSEGV) 和 Segment Register 两个 Segment 的区别到第是什么呢?
Reference
- https://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
- https://en.wikipedia.org/wiki/Endianness
- https://www.cnblogs.com/hackmylife/p/9781481.html
本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.