|
|
@ -237,9 +237,9 @@ fn main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
例子中,我们使用 `cpuid` 指令来读取 CPU ID,该指令会将值写入到 `eax` 、`edx` 和 `ecx` 中。
|
|
|
|
例子中,我们使用了`cpuid` 指令。这个指令会将CPU的最大cpuid参数写入`eax`中,同时将CPU的生厂商ID以ASCII字符的形式写入到 `ebx` 、`edx` 和 `ecx` 中。
|
|
|
|
|
|
|
|
|
|
|
|
即使 `eax` 从没有被读取,我们依然需要告知编译器这个寄存器被修改过,这样编译器就可以在汇编代码之前存储寄存器中的值。这个需要通过将输出声明为 `_` 而不是一个具体的变量名,代表着该输出值被丢弃。
|
|
|
|
即使 `eax` 从没有被读取,我们依然需要告知编译器这个寄存器被修改过,这样编译器就可以在执行汇编之前存储寄存器中的值。这个需要通过将输出声明为 `_` 而不是一个具体的变量名,代表着该输出值被丢弃。
|
|
|
|
|
|
|
|
|
|
|
|
这段代码也会绕过一个限制: `ebx` 是一个 LLVM 保留寄存器,意味着 LLVM 会假设它拥有寄存器的全部控制权,并在汇编代码块结束时将寄存器的状态恢复到最开始的状态。由于这个限制,该寄存器无法被用于输入或者输出,除非编译器使用该寄存器的满足一个通用寄存器的需求(例如 `in(reg)` )。 但这样使用后, `reg` 操作数就在使用保留寄存器时变得危险起来,原因是我们可能会无意识的破坏输入或者输出,毕竟它们共享同一个寄存器。
|
|
|
|
这段代码也会绕过一个限制: `ebx` 是一个 LLVM 保留寄存器,意味着 LLVM 会假设它拥有寄存器的全部控制权,并在汇编代码块结束时将寄存器的状态恢复到最开始的状态。由于这个限制,该寄存器无法被用于输入或者输出,除非编译器使用该寄存器的满足一个通用寄存器的需求(例如 `in(reg)` )。 但这样使用后, `reg` 操作数就在使用保留寄存器时变得危险起来,原因是我们可能会无意识的破坏输入或者输出,毕竟它们共享同一个寄存器。
|
|
|
|
|
|
|
|
|
|
|
|