我目前正在开发一个编译器,它将源代码转换为汇编,然后使用
nasm
实际汇编代码。我在这种语言中的目标是拥有像 C 风格语言那样的整数声明,其中我将拥有 int8
、int16
、int32
和 int64
,因为它们映射到 db
、dd
、dw
,和dq
在组装中。我已经尝试过做类似的事情:
num_1 db 300
我看到显示溢出警告,但我在理解以下内容时遇到了一些麻烦:
section .text
global _start
section .int_8 write
int_8 db 5
section .text
_start:
mov al, [int_8]
push 300
pop rbx
add rax, rbx
如果我通过
gdb
运行代码并查看发生了什么,我可以看到在 add
调用之后,info registers rax
显示 305
正如我所期望的。如果我运行 info registers al
只访问前 8 位,我会看到 49
。我是否正确地假设我看到 49
是因为值已经换行 (305 - 256 = 49)?如果这是正确的,在汇编中是否有办法引发缓冲区溢出以保持代码“安全”?意思是如果我超过了 256
的最大大小,则会引发缓冲区溢出警告,而不是仅仅包装值?
附录
感谢评论中的每个人,我有一些简单的 8 位整数加法溢出检查代码,如下所示:
pop rcx ;; Get return address
pop rax
movzx rbx, al ;; Move 8 bits into the rbx registery
cmp rax, rbx
je no_overflow_int_8
jne has_overflow_int_8
no_overflow_int_8:
push rcx
ret
has_overflow_int_8:
mov rax, 60
mov rdi, 8
syscall
这将因某些任意退出代码而出错。但是,当我去检查32位溢出时。我发现,如果我将像
4294967290
这样声明为 dd
的值加载到 rax
中,然后我使用 info registers eax
查看该值,我会看到一个负数。因此,检查变成了确定添加后的eax
是否大于0,这似乎不正确,因为如果我使用100
,eax
中的值实际上是100。我有点困惑,因为为什么rax
正确显示数字但eax
是负数。我假设我可以将 2^32
作为最大整数值放入 eax
但也许我误解了什么?