Pointers 你能用汇编语言减去两个指针吗?

Pointers 你能用汇编语言减去两个指针吗?,pointers,assembly,x86,intel,addressing,Pointers,Assembly,X86,Intel,Addressing,我遇到了以下代码,并试图从概念上理解它: 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 假设它们是相对于相同段基的偏移量,例如一个微小/小或平坦的内存模

我遇到了以下代码,并试图从概念上理解它:

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提到的一个用例是:从指针获取数组索引。e、 你可以通过增加一个指针来实现strlen,然后在末尾执行sub ax,si来返回一个长度

当然,对于当前文件中定义的标签,距离是一个汇编时间常数,因此您应该让汇编程序为您计算距离。我认为movsi,OFFSET v5-v2是正确的MASM语法。在NASM中,它将只是mov si,v5-v2。使用这些定义,无论是在汇编时使用v5-v2还是使用运行时子指令,都会得到si=2,因为dw 4的宽度为2字节

或者,将2个数组输入作为2个指针+一个长度的函数可以通过减去并获取绝对值来检查重叠是否小于长度。看


它与C语言中的减法指针完全相同,只是您控制静态数据的布局,因此对它的意义或任何未定义的行为没有限制。除了在C中,指针减法按类型宽度缩放。所以这实际上就像在减法之前对uintptr\t进行强制转换。

是的,指针只是整数,当然你可以减去它们,比如用sub-si,di

假设它们是相对于相同段基的偏移量,例如一个微小/小或平坦的内存模型,结果实际上是有意义的:指向内存位置之间的距离(以字节为单位)

@fuz提到的一个用例是:从指针获取数组索引。e、 你可以通过增加一个指针来实现strlen,然后在末尾执行sub ax,si来返回一个长度

当然,对于当前文件中定义的标签,距离是一个汇编时间常数,因此您应该让汇编程序为您计算距离。我认为movsi,OFFSET v5-v2是正确的MASM语法。在NASM中,它将只是mov si,v5-v2。使用这些定义,无论是在汇编时使用v5-v2还是使用运行时子指令,都会得到si=2,因为dw 4的宽度为2字节

或者,将2个数组输入作为2个指针+一个长度的函数可以通过减去并获取绝对值来检查重叠是否小于长度。看


它与C语言中的减法指针完全相同,只是您控制静态数据的布局,因此对它的意义或任何未定义的行为没有限制。除了在C中,指针减法按类型宽度缩放。因此,这实际上就像在减法之前对uintptru\t进行强制转换。

指针之间的差异是它们指向的对象之间的距离。这有时很有用,例如从指向数组元素的指针中找出数组元素的索引。对于处理器来说,它们只是位,不是浮点,不是指针,也不是整数。只是点点滴滴。只有在那短暂的一瞬间,它们才可能是其他的东西,然后回到位。指针之间的区别是它们指向的对象之间的距离。这有时很有用,例如从指向数组元素的指针中找出数组元素的索引。对于处理器来说,它们只是位,不是浮点,不是指针,也不是整数。只是点点滴滴。只有在那短暂的一刻进行手术后,它们可能会变成其他东西,然后又会变成碎片。