记一次 Rust 类型系统的问题解决
在做 Codeforces Educational Round 169 D Colored Portals 时,需要找到 i 前面距离 i 最近的颜色不完全相同但也不完全不同的 j,我随手写了个
1 | const vector<string> type = {"BG", "BR", "BY", "GR", "GY", "RY"}; |
在做 Codeforces Educational Round 169 D Colored Portals 时,需要找到 i 前面距离 i 最近的颜色不完全相同但也不完全不同的 j,我随手写了个
1 | const vector<string> type = {"BG", "BR", "BY", "GR", "GY", "RY"}; |
无符号的数的加法溢出规则很简单, 单纯截取后 \(w\) 位, 或称对 \(2^w\) 取模。因此:
\[ x\ +_w^u\ y = \begin{cases} x + y, & x + y < 2^w, \\ x + y - 2^w, & 2^w \leq x + y < 2^{w+1}. \end{cases} \]
(\(+_w^u\) 表示最多 \(w\) 位下的二进制无符号数加法。下文\(+_w^t\) 即 \(w\) 位补码加法)
若 \(s = x +_w^u y\), 当且仅当 \(s < x\) (或等价地 \(s < y\)) 时发生溢出。
(当然, 默认 \(x\) 和 \(y\) 本身不会溢出, 即在 \([0, UMax_w]\) 的范围内)
原理易证, 分别证明充分性必要性即可, 注意利用以上公式
博客还没装 Mathjax 插件,所以下面的 \(\LaTeX\) 应该都是乱的 已修
这一段如果没有目的和顺序地硬看会觉得关系很多很复杂,但其实只要按照一定的目的和顺序结构就会很清晰。
如果我们是设计用二进制表示整数的人,我们需要如何表示二进制?
利用 \(w\) 位二进制的最高位 $ x_{w-1} $ 为 \(1\) 代表这个数是负数,剩下的部分正常用二进制表示即 \(\displaystyle\sum_{i=0}^{w-2}x_i\cdot2^i\)
但显然光表示是完全不够的,我们还需要运算,而符号位由于不对具体数值做贡献,会导致运算错误。
因此我们需要让符号位也代表数值,用另一种映射方式计算,于是我们令最高位的符号位具有负的权重
\(-x_{w-1} \cdot
2^{w-1}\),这样符号位也参与了计算。但是这样数值又对不上了,因此我们需要把后面的位也变一下。由于我们不是真的设计师,所以我们直接看答案:取反后面的每一位后再
+1。例如10010除符号位取反后变为11101,
+1后是11110。这样的表示方法计算出的数值是 \(-x_{w-1}\cdot2^{w-1}+\displaystyle\sum_{i=0}^{w-2}x_i\cdot2^i\)
如何论证这样的数值是”对”的呢?
一个练手的,要求通过缓冲区栈溢出攻击来调用 touch1
gdb ctarget 然后 set args -q
防止与不存在的服务器通信(run -q 也可以)
b Gets run -q
看一下栈信息:
1 | ────────────────────────[ STACK ]──────────────────────── |
这是我第一个完成的 lab, 这篇博客其实是边做边记的解决过程改的, 所以比较简略, 其他 Lab 的记录博客会详细一点, 这篇博客以后有时间也会补充
Border relations with Canada have never been better.
根据调用约定, gdb 直接读 phase_1() 的 $rdi
即可.
1 2 4 8 16 32 利用断点跳到 read_six_number
后, 发现核心代码 add %eax %eax, 即不断 \(\times 2\)
5 206 rsp+8, rsp+12
分别是输入的两个数, int 占四字节.
发现一堆 mov, jmp, 里只有第五个的差能整除
\(8\) 并且 mov 过去的值是
206
(最后几行是核心代码 cmp 0xc(%rsp), %eax)
此文章的 撰写时间 可能有误
这篇博客会更新一段时间。 本文已弃用, 这一章的博客记录在 CSAPP3e第二章(整数的表示)
| Amiriox’s Storage
此文章的 撰写时间 可能有误
upd 2024-10-02 22:56:57
第一次用感觉还行,后来高三又从win换回opensuse,感觉挺垃圾的
今天太晚了等明天把我那篇批判的文章迁移过来
一直在考虑是否要换个linux玩玩。 自从10月1日(其实是10月2日凌晨)装好了manjaro 我就没停过折腾这玩意。
此文章的 撰写时间 可能有误
对于x<<k称为将 \(x\) 左移 \(k\) 位。 对于一个位向量表示为 \([x_{w-1}, x_{w-2}, ..., x_0]\) 的操作数
\(x\), x<<k的结果是$
[x_{w-k-1}, x_{w-k-2}, …, x_0, 0, …, 0] $ 也就是向左移动 \(k\) 位, 右侧空缺用0补齐。
在C中,左移运算符从左至右结合。即x<<i<<j相当于(x<<j)<<k
对于x>>k成为将 \(x\) 右移 \(k\) 位。
不同的是,右移有两种形势,算术右移和逻辑右移。