to 1#,其实还是编译器(准确讲叫连接器)的工作,搞成操作系统对应的文件结构,然后操作系统加载并创建进程执行相应内容。跟组成原理关系不大。
GuuJiang
2022-12-03 21:56:01 +08:00
不知道你有没有遇到过在 Windows 系统上弹出一个错误提示,内容为“非法指令” 你这个问题要分几个层次来回答 1. 计算机怎么区分机器码和其它内容 每种架构的 CPU 有个东西叫做指令集,规定了哪些是合法的指令,CPU 总是无条件地把程序寄存器指向的内容当成指令(哪怕由于堆栈破坏等原因导致程序寄存器指向了数据段或者其它无效内容),尽量地去尝试译码,如果确实碰到了无法译码的内容则产生中断 2. 上面是从单条指令的角度来说,但是我猜你可能误认为 CPU 是直接执行编译输出的文件,所以会有这个疑问,实际上编译生成的可执行文件要遵循目标操作系统上的可执行文件的特定结构,例如 PE 、elf 等,而操作系统在加载可执行文件时首先依据文件结构找到其中的代码段,然后才是交给 CPU 执行
Jooooooooo
2022-12-03 22:09:03 +08:00
按照位置来的
比如有个起始符
START 识别完这个之后, 后面紧跟就是一个 指令+数据, 然后如此反复
有一种攻击方法, 就是错乱这个识别, 让机器把数据识别成指令, 就可以执行任意想执行的东西了
你可以研究下 JAVA 代码编译成的 .class 文件机器是怎么读取的就明白了
ww2000e
2022-12-03 22:35:44 +08:00
如果是汇编器,那是按照 cpu 硬件定好的规矩生成的二进制,如果是高级语言的,还要过一道操作系统,二进制按操作系统要求格式生成的,二进制本身依然还是按 cpu 硬件要求生成
当你运行一个程序的时候,操作系统会读取这个程序的内容到内存,解析它的结构,并告诉 CPU 「从这个地方开始执行」。也就是说,CPU 并不会去尝试「区分」一块内存是指令还是数据(也没办法区分),只是从某个地方开始,一条一条地执行下去,遇到跳转指令再改变当前读取指令的位置(即所谓的 Program Counter 寄存器)。所有从某个位置读数据的操作,都是指令告诉 CPU 去读的。