assembly 当我们写PUSH命令时,堆栈和sp会发生什么变化?(汇编)

trnvg8h3  于 2023-01-09  发布在  其他
关注(0)|答案(3)|浏览(244)

我刚开始学习汇编,我和我的朋友对下面命令中到底发生了什么有不同的想法:
推送1234 h
我们的问题是:第一个数字(12)将进入堆栈的哪个位置?
ss:[sp-2]?
保安司:[保安司-4]?

  • sp =堆栈指针
rxztt3cl

rxztt3cl1#

假设你使用的是x86硬件(因为你指定了sp寄存器),字节将从高位(最高有效位)到低位(最低有效位)被压入。在这种情况下,它将压入字节12h,然后是字节34h。由于x86堆栈指针在你压入项时减小,内存布局看起来像这样:

[sp+1] = 12h
[sp]   = 34h

如果将[sp]作为一个单词(两个字节)访问,则会得到原始值:

[sp] = 1234h
tvokkenx

tvokkenx2#

信不信由你,但你们两个都可能是对的。字节顺序取决于机器的endianness

nwlls2ji

nwlls2ji3#

在真实的模式下(看起来像是在为它编写程序),首先计算地址,公式非常简单:

address = (segment<<4)+offset

然后将此地址减去您尝试推送的元素的大小(word:2个字节,dword:4个字节,qword:第三步是在结果位置上写入数据。因此,如果SS0x30并且SP0xFF,则:

  1. address = (0x30<<4)+0xFF = 0x3FF
    1.元素是单词,所以我们减去2position = 0x3FF - 2 = 0x3FD
    1.在结果位置写入数据(作为C指针):一米十纳米一x一米十一纳米一x
    因此,byte SS:[SP] = 0x34byte SS:[SP+1] = 0x12。请注意,堆栈向下增长/扩展,因此不会有SP-x,而是SP+x
    在保护模式下,事情有点复杂(我在这里只写使用段寄存器的过程):
    1.首先,处理器获取全局描述符表描述符(由LGDT指令加载)的地址。
    1.处理器将段寄存器的值与GDT的大小进行比较(如果大于,则抛出异常)。它还检查段寄存器是否未指向空描述符(SS!=0
    1.然后,处理器获取指向GDT条目的指针,并计算从GDT开始的偏移量(使用SS*8)。
    1.处理器必须检查一些事项:
    4.1.段是否存在?4.2.我们是否有足够的权限访问段?4.3.是否为代码段?4.4.是否可写?4.5.是否为ESP*granularity+base < limit 4.6.是否为系统段?
    1.然后通过base_of_segment+ESP计算地址。
    1.之后,它继续类似于真实的模式。

相关问题