pointers - 你能用汇编语言减去两个指针吗?
问题描述
我遇到了以下代码,并试图从概念上理解它:
mov si,offset v5
mov di,offset v2
sub si,di
v5
并v2
参考以下数据:
v2 dw 4
v5 dw 3
所以从我的理解来看,这似乎触及了 x86 汇编语言中间接寻址的概念。我知道 si 和 di 寄存器不等于值,而只是指向位置。因此,像上面的代码那样减去两个指针会得到什么答案?可行吗?
解决方案
是的,指针只是整数,当然你可以减去它们,例如用sub si, di
.
假设它们是相对于同一段基础的偏移量(例如,微小/小型或平坦的内存模型),结果实际上是有意义的:指向的内存位置之间的字节距离。
@fuz 提到的一个用例是:从指针获取数组索引。例如,您可以strlen
通过增加一个指针来实现,然后在最后sub ax, si
返回一个长度。
当然,对于当前文件中定义的标签,距离是一个汇编时间常数,所以您应该让汇编程序为您计算它。我认为 mov si, OFFSET v5 - v2
是正确的 MASM 语法。在 NASM 中,它只是mov si, v5 - v2
. 有了这些定义,你就会si=2
知道你是在汇编时用v5 - v2
还是用运行时sub
指令来做的,因为dw 4
它有 2 个字节宽。
或者一个将 2 个数组输入作为 2 个指针 + 一个长度的函数可以通过减去并取绝对值来检查它是否小于长度来检查重叠。请参阅在 64 位 x86 中指针比较应该是有符号还是无符号?
这与 C 中的减指针完全一样,只是您可以控制静态数据的布局,因此对有意义的操作或任何未定义的行为没有限制。(除了在 C 中,指针减法按类型宽度缩放。所以它实际上就像uintptr_t
在减去之前强制转换。)
推荐阅读
- symfony4 - 如何使用同一网络从另一台计算机访问 symfony 4 本地项目
- spring-boot - 为 SpringCloud 传播额外字段/新字段分布式跟踪解决方案。在 BootClass 中配置
- javascript - 如何在 javascript 代码中从收件箱中读取电子邮件
- python - 导入 numpy 时未定义“arange”
- c++ - 为什么比较函数类型需要指定为模板参数?
- python - 从熊猫数据框中生成字典,将多列组合为键,其余列作为值?
- sql-server - 将 pandas 数据帧写入 MSSQL datetimeoffset 列时缺少时区偏移
- android - SAF - 解码的 Uris 似乎被认为与 SAF 方法编码的 Uris 不同
- angular - 为给定对象定义接口时出错
- r - 在r中使用带有迭代计算的优化函数