程序与指令
由于.o文件还未进行链接,所以其地址是不确定的,所以代码从地址0开始
可执行文件其代码的开始地址是虚拟地址
《IA-32的ISA》
所以可知道IA-32 是一个32位的指令系统
《IA-32体系结构》
在这里我们要知道
AI-32其有8个8位寄存器,8个16位寄存器,8个32位寄存器
《AI-32的指令》
其源地址与目的地址是与Intel格式汇编是相反的
以下面那个汇编为例:
这里是将 寄存器EDX与寄存器EAX地址相加
再加上偏移量1
得到的值传给寄存器EAX
lea 后的l表示传的是双字
再以寻址方式为例:
M[]就表示要访存,不再是立即数或者寄存器之间的数据了
以第一个push %ebp 进行讲解:
首先我们要明确EBP其是基址指针一般其是保存存储器的地址
以及ESP其是堆栈指针一般也是用来保存寄存器的地址
我们让R[esp]-4 -> R[esp] 是为了让栈指针移动
然后将 R[ebp]中的内容保存到 存储器中的 地址为R[sep]的地方
再来看lea (%edx,%eax,1), %eax
表示将 %edx(EDX寄存器中的数据,其保存的一般是存储器中的地址) + %eax(同理) +1 的值
给 寄存器 EAX
一般像这么写,基址+偏移量 ,那是要访存了
《指令的基础----加法器》
首先我想提出一个问题:
你能否通过这个真值表来写成逻辑表达式
在通过逻辑表达式化简得到?
解:
于是就可以得到逻辑表达式了
化简呢? 靠离散数学功底了
解释:
OF 是用来判断带符号整数运算时,是否溢出的标志位
其在无符号整数运算时是无效的
CF是用来判断无符号整数运算时,是否溢出(无符号整数运算最后有进位/借位就说明其溢出了)
其在带符号整数运算时是无效的
CF还可以写成 CF=Cout ^ Sub (^表示异或,Sub是进行减运算的符号位,1表示进行减运算)
能有这种写法是因为:
Cin (也可以写成Sub)作为 一种信号,提示是否是减运算
MUX是多路选择器
通过Sub信号选择是B参与运算,还是按位取反+1的B进行运算
我们知道带符号整数在机器中是通过补码表示的
当我们在程序中写了:
在机器中就被转化成了补码
[x]补=0000....1001,[y]补=1111.....1010
以z2运算为例:
这里让A=x,B=y进行讲解
当这两个数到达加法器后,B分出两条线
一条是B,另一条是按位取反+1的B(即B的补码)
我们知道在计算机中进行减法是将减数求补码+被减数,这里也是这样
因为这里是-,则Sub=1 选出了 按位取反+1的B
然后进行运算
注意一旦溢出,说明运算结果都是不对的
上述进行包装得到ALU:
《为何需要标志位?》
其实像i>j的这种条件判断都是通过加减运算,然后得到标志位
通过标志位上的信息来判断结果
如:
还有个疑惑点:
为何是这个公式(即这些公式咋来的)?
《逻辑运算与位移指令》
需要注意一下逻辑右移和算术右移的区别:
逻辑右移是对于无符号整数移动时用的,其在往右移动时只在左边补0
而算术右移是对于带符号整数移动时用的,其在右移时根据最高位的符号在左边补0/1
《条件转移指令》
如下这张图更好地说明了标志位的作用:
解释:
这里的大锅其实要交给unsigned len
这里的无符号整数len导致在进行条件比较时,是按照无符号整数的规则进行比较
(注意所谓无(带)符号整数的比较规则是转移条件的不同
如无符号整数是否溢出看CF,而带符号整数是否溢出看OF)
注意ALU是无情执行的机器,其才不管什么是无符号还是带符号
其只管对给出的二进制进行运算,然后取低n位(这里的n是指能运算最大位数)
本文作者:次林梦叶
本文链接:https://www.cnblogs.com/cilinmengye/p/17341810.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2022-04-21 快速幂----但是是数组版本,高精度