【问题标题】:NASM - is this the address, value?NASM - 这是地址,值吗?
【发布时间】:2015-09-05 10:39:00
【问题描述】:

TL;DR

[memloc] 是指值还是地址?如果它指的是任何一个,那么为什么它既可以作为值作为地址呢? (参见下面的代码,第 4 行和第 5 行)

完整问题...

抱歉,问题太长了。 我对 NASM 中的标签取消引用感到困惑。举个例子:

01| section .text
02| ; exiting the program with exit code "15"
03|
04| mov     [memloc], 15 ; move 15 into memloc
05| push    [memloc]     ; push memloc on stack
06| mov     eax, 1       ; prepare exit syscall
07| call    kernel       ; invoke syscall
08|
09| section .data
10| memloc: dd 0    ; let's say this is at address 0x1234

当我运行它时,它以代码 15 退出。它可以工作!
...但是为什么?memlock 不应该没有大括号第 4 行,其中push 大概期望目的地?

例如:
04 行的 mov 指令将值 15 移动到 memloc 的 ADDRESS:

mov     [memloc], 15 ; move 15 into mem @memloc

05 行将存储在 memloc 中的 VALUE 推入堆栈:

push    [memloc]     ; push value @memloc on stack

那么,[memloc] 是值 (15) 还是地址 (0x1234)?如果你改为mov memloc, 15,理论上会发生什么?

提前谢谢你。

【问题讨论】:

  • 如果操作根据您是否在其周围放置大括号来区别对待其操作数,那么我想我的问题是“机器代码如何区分地址和值?”
  • 它没有,这就是你必须在它周围放大括号的原因。

标签: syntax nasm dereference


【解决方案1】:

mov 指令有多个版本。如果编译器 (NASM) 看到 memloc 周围的方括号,它会生成mov 的一种形式,如果你的编译器没有看到 memloc 周围的方括号,它会生成另一种形式mov 的形式。

考虑以下说明:

mov edx, memloc
mov edx, [memloc]
mov [memloc], edx

它们都是 mov 到/来自同一个目标/源寄存器 EDX,但编译器 (NASM) 将为这些指令生成完全不同的操作码。

第一个mov 编码为 5 个字节 0xBA、?、?、?、?
第二个mov 编码为 6 个字节 0x8B、0x15、?、?、?、?
第三个mov用6个字节编码0x89、0x15、?、?、?、?

这 4 个 ? 代表 NASM 分配的 memloc 的地址。
在您的问题中使用示例地址 (0x1234) 这将变为:

第一个mov用5个字节0xBA、0x34、0x12、0x00、0x00编码
第二个mov编码为6字节0x8B、0x15、0x34、0x12、0x00、0x00
第三个mov编码为6个字节0x89、0x15、0x34、0x12、0x00、0x00

【讨论】:

  • 这绝对是造成我困惑的原因。我在想括号表示参考的变化,当它们真正改变操作时。谢谢你的回答!
【解决方案2】:

如果你改为mov memloc, 15,理论上会发生什么?

NASM 不会除此之外,因为您不能将立即值 (15) 移动到另一个立即值 (memloc)。

第04行的mov指令将值15移动到memloc的ADDRESS:

第 4 行的指令不会改变 memloc 的地址。
就像第 5 行一样,它使用存储在 memloc 中的值。

那么,[memloc] 是值 (15) 还是地址 (0x1234)?

[memloc] 是值 15
memloc 是地址 0x1234(在代码的第 10 行设置后,您无法更改)

【讨论】:

  • 好的,但是mov 指令必须知道它放置信息的地址。就像我告诉您将邮件放入邮箱一样,您需要知道邮寄地址。我不能把盒子里的邮件给你,然后指望你神奇地找到它,对吧? (假设所有邮件都没有地址,哈哈)
  • @JamesM.Lay mov 指令的版本不止一个。如果编译器 (NASM) 看到 memloc 周围的方括号,它会生成mov 的一种形式,如果你的编译器没有看到 memloc 周围的方括号,它会生成另一种形式mov 的形式。
  • @user3144770 所以,当你mov [mem], eax 时,地址仍然被传递,但是传递给期望偏移量的操作码?因此,与其将mem 视为“查找和替换”目标,不如将其视为C 指针,其中mov [mem],eax 类似于*mem = eaxpush [mem] 类似于push(*mem)
  • (...如果有一个类似的函数可以压入 c 中,让您以编程方式访问堆栈。)
  • @user3144770 如果您将其作为答案发布,我会接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多