首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >来自BP (emu8086程序集)的可变偏移量

来自BP (emu8086程序集)的可变偏移量
EN

Stack Overflow用户
提问于 2022-08-15 00:03:59
回答 1查看 101关注 0票数 2

我的编译器任务的一部分包括将C程序转换为8086程序集。假设我在C中有以下内容:

代码语言:javascript
复制
int a[3];

此数组声明的转换程序集代码如下所示(默认情况下假定初始化为0,我必须对局部变量使用堆栈分配):

代码语言:javascript
复制
MOV BP, SP
PUSH 0 ; [BP-2] refers to a[0]
PUSH 0 ; [BP-4] refers to a[1] 
PUSH 0 ; [BP-6] refers to a[2]

假设我必须将以下C代码转换为程序集:

代码语言:javascript
复制
a[2]=5;

索引的计算方式如下:

代码语言:javascript
复制
; offset from BP for a[idx] = offset for a[0] + idx * 2

MOV AX, 2 ; AX = idx
MOV BX, 2 ; multiplier
MUL BX    ; DX:AX = idx * 2 (*ignore DX for now*)
MOV BX, 2 ; AX = offset for a[0] = 2
ADD AX, BX; AX = 4 + 2 = 6
MOV [BP-AX], 5

赋值规范保证索引*2永远不会超过16个字节,因此DX在乘法后总是包含0000H

问题在于最后一行MOV [BP-AX], 5AX不能从BP中减去,但为了这个目的,我需要做到这一点。我该如何解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-15 01:15:47

您的内存布局是反向的。数组应该始终放在内存中,从低地址到高地址,即使在堆栈上也是如此。所以你应该

代码语言:javascript
复制
a[0] at bp-6
a[1] at bp-4
a[2] at bp-2

因此,您的代码应该更类似于:

代码语言:javascript
复制
;; compute the offset 4 in AX as you have already done
MOV DI, AX
MOV WORD PTR [BP-6+DI], 5

因此,数组的基础总是在BP-6,然后索引到它总是涉及加法,而不是减法。您不能在16位8086上使用AX作为索引寄存器,但是可以使用SIDI。( ecm指出,还需要WORD PTR告诉汇编程序生成两个字节的存储指令,而不是一个字节。)

(您可能想知道为什么在有效地址中允许“减法”常量位移,而不允许减法索引寄存器。从技术上讲并非如此,指令只能编码16位恒定位移的加法。但是汇编程序会为您处理这个问题,将[BP-6+DI]编码为常量-6的加法。它相当于[BP+(-6)+DI][BP+0FFFAh+DI]。)

您可以通过计算DI中的偏移量而不是AX来提高效率,从而避免额外的MOV DI, AX。此外,如果您的编译器能够计算出sizeof(int)是常量2,那么为了提高效率,应该使用SHL而不是MUL进行乘2的运算。所以它可能想看起来更像

代码语言:javascript
复制
MOV DI, 2 ; or some code choosing index 2 at runtime
SHL DI, 1 ; multiply by sizeof(int) which is 2
MOV WORD PTR [BP-6+DI], 5

当然,如果索引2确实是一个常量,那么理想的情况是将整个过程优化为MOV WORD PTR [BP-2], 5

更普遍的是,如果您不能在一条指令中完成您想做的事情,那么只需发出更多的指令就可以在多个步骤中完成它。在某些情况下,您可能需要使用其他寄存器。

如果您确实希望将数组倒转并实现您最初要求的效果,那么您可以这样做,例如:

代码语言:javascript
复制
; compute offset in AX as you have done
MOV DI, AX
NEG DI
MOV WORD PTR [BP+DI], 5

您还可以在另一个寄存器中单独计算整个地址。BXSIDI都能工作。请注意,默认情况下,它们会寻址DS段,而BP则会处理SS段。因此,如果您所处的代码模型中的堆栈和数据段可能不同,则需要分段覆盖。

代码语言:javascript
复制
; compute offset in AX as you have done
MOV BX, BP
SUB BX, AX
MOV WORD PTR SS:[BX], 5
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73355894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档