【问题标题】:Access stack directly直接访问堆栈
【发布时间】:2021-08-16 12:36:50
【问题描述】:

此问题与nasm Intel: Access items in the stack without using pop有关

我的数据、代码和堆栈段是之前设置的,以覆盖全部内存。

我尝试使用以下代码直接访问堆栈:

[bits 32]
[org 0x0]

mov ah, 0x62
mov al, 'H'
push ax

mov esi, 0x90000 ;(esp is 0x90000)
sub esi, 4

mov word ax, [esi]

mov word [0xB8A00], ax
jmp $

它应该打印一个 H,但它什么也没打印。我不明白我做错了什么,我也尝试删除 sub esi, 4,结果相同。我也尝试过切换 ah & al 的内容(因为 little endian,我保留了这个顺序)

【问题讨论】:

  • push ax 仅将 ESP 减少 2,而不是 4;也许你的意思是push eax。使用调试器查看寄存器值和内存内容。

标签: assembly operating-system nasm


【解决方案1】:
mov esi, 0x90000 ;(esp is 0x90000)

这是您的代码中令人担忧的部分。即使您说“esp is 0x90000”,防御性程序员也会将其写为mov esi, esp。这样做可以避免知道太多的问题。

将字符代码和属性字节放在堆栈上的代码将使堆栈指针指向这对字节。无论您使用push ax 还是push eax,这都是正确的。

如果你对内存有线性访问,确保DS等于SS,并且屏幕设置正确(*),接下来sn-p会将GreenOnBrown大写“H”放在第一个屏幕第十七行的列:

mov  ah, 0x62
mov  al, 'H'
push ax
mov  esi, esp
mov  ax, [esi]
mov  [0xB8A00], ax

作为替代方案,使用ESP 相对寻址:

mov  ah, 0x62
mov  al, 'H'
push ax
mov  ax, [esp]
mov  [0xB8A00], ax

(*) 总是问自己,显存中的地址是否在硬件使用其内容来更新屏幕的地址中!

  • 对于 80x25 文本屏幕,硬件可能会从您期望的显示页面 0 以外的显示页面更新。
  • 对于 40x25 文本屏幕,地址 0xB8A00 不在显示的缓冲区范围内。

【讨论】:

  • 出于学校原因,我试图不故意使用 esp register 并了解堆栈的工作原理。这很好解释,可能会帮助很多学生。谢谢你这么清楚的解释。
猜你喜欢
  • 2015-02-02
  • 2014-04-03
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 2020-03-20
  • 2018-06-15
相关资源
最近更新 更多