如何获取变量的地址并在 nasm x86 程序集中取消引用它?

2024-03-23

在c语言中我们使用&获取变量的地址并*取消引用该变量。


    int variable=10; 
    int *pointer;
    pointer = &variable;

汇编中没有变量。 (*)

variable db 'A'

做几件事。它定义了汇编时间符号variable,就像内存中的书签,包含地址*here*在编译的时候。这与在空行上做标签是一样的,例如:

variable:

The db 'A'指令是“定义字节”,并且您为其定义要定义的单字节值,因此它将在结果机器代码中生成带有值的单字节0x41 or 65以十进制表示。这就是 ASCII 编码中大字母 A 的值。

Then:

mov ecx , [variable]

是否从地址处的内存单元加载 4 个字节variable,表示低8位ecx将包含该值65,并且高24位将包含一些垃圾,这些垃圾恰好驻留在后面的3个字节中'A'..(你会用db 'ABCD',那么ecx将等于价值0x44434241 ('D' 'C' 'B' 'A'字母,由于小端编码而以位“反转”dwordx86 上的值)。

But the sys_write期望ecx保存存储内容字节的内存地址,因此您需要:

mov ecx, variable

这将在 NASM 中将数据的地址加载到ecx.

(在 MASM/TASM 中,这将组装为mov ecx,[variable]要获取地址,您必须使用mov ecx, OFFSET variable,如果您碰巧找到一些 MASM/TASM 示例,请注意语法差异)。


*)有关“无变量”的更多信息。请记住,在装配过程中,您处于机器级别。在机器级别上有计算机内存,可以按字节寻址(在x86平台上!有一些平台,内存可以按不同大小寻址,它们并不常见,但在微控制器世界中您可能会找到一些)。因此,通过使用某些内存地址,您可以访问物理内存芯片中的某些特定字节(对内存芯片中的特定物理位置进行寻址取决于您的平台,现代操作系统通常会为用户应用程序提供虚拟寻址空间,转换为CPU 动态、透明地处理物理地址,而不会影响用户代码的转换)。

所有高级逻辑概念(例如“变量”、“数组”、“字符串”等)都只是内存中的一堆字节值,所有逻辑含义都是由正在执行的指令赋予内存数据的。当您在没有指令上下文的情况下查看这些数据时,它们只是内存中的一些字节值,仅此而已。

因此,如果您的代码不精确,并且您通过指令获取来访问单字节“变量”dword,就像你在你的mov ecx,[variable]例如,从机器的角度来看,这没有什么问题,它会很乐意将 4 个字节的内存读取到ecx注册,NASM 也懒得报告您,您可能越界访问超出原始内存的内存variable定义。如果您用“变量”等术语和其他高级编程语言概念来思考,这是一种愚蠢的行为。但汇编不是为了这样的工作,实际上对机器的完全控制是汇编的主要目的,如果你想获取4个字节,你可以,这完全取决于程序员。它只需要极高的精度,关注细节,了解内存结构布局,并使用正确的指令和所需的内存操作数大小,例如movzx ecx,byte [variable]从内存中仅加载单个字节,并将该值零扩展为目标中的完整 32b 值ecx登记。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取变量的地址并在 nasm x86 程序集中取消引用它? 的相关文章

  • 本机代码、机器代码和汇编代码有什么区别?

    我对 NET 语言上下文中的机器代码和本机代码感到困惑 它们之间有什么区别 它们是一样的吗 这些术语确实有点令人困惑 因为它们有时使用不一致 机器代码 这是定义最明确的一种 它是使用字节码指令的代码 您的处理器 执行实际工作的物理金属部件
  • 指向数组的指针如何工作?

    int s 4 2 1234 56 1212 33 1434 80 1312 78 int p 1 p s 0 printf d n p 0 1234 printf d n s 0 0 1234 printf u n p 1256433 a
  • 为什么数组变量的地址与它本身相同? [复制]

    这个问题在这里已经有答案了 在 C 语言中 如果我们有一个像这样的数组a 10 then a and a具有相同的指针值 但类型不同 我想知道为什么C要这样设计 这是为了节省存储所需的额外空间吗 a 当您想到这一事实时 这是有道理的a永远不
  • 汇编:使用数据段寄存器(DS)

    目前我正在学习 x86 汇编 因为我喜欢微控制器编程 所以我熟悉汇编 目前我一直在到处寻找这个问题的答案 但似乎找不到它 DS寄存器 我知道它应该指向我程序中的全局数据 但我不知道知道它到底是如何工作的 我正在使用 NASM 在大多数简单的
  • 字符数组的文字字符串初始值设定项

    对于数组衰减为指针的情况 规则如下 出现在表达式中的 array of T 类型的左值 参见问题 2 5 衰减 有三个例外 为指向其第一个元素的指针 结果指针的类型是指向 T 的指针 例外情况是数组是 sizeof 或 运算符的操作数 或者
  • 通过引用传递参数到指针问题

    每次我尝试编译代码时都会收到错误 cannot convert parameter 1 from int to int 测试代码如下所示 void set int val val 10 int main int myVal int pMyV
  • 安全移动 C++ 对象

    我听到过一些警告 不要通过以下方式将对象运送到另一个内存位置memcpy 但不知道具体原因 除非它包含的成员做了依赖于内存位置的棘手事情 否则这应该是完全安全的 或者不是 编辑 预期的用例是像这样的数据结构vector 它存储对象 不是po
  • 删除指针后将其设为 NULL 是一个好习惯吗?

    我首先要说的是 使用智能指针 您将永远不必担心这个问题 下面的代码有什么问题 Foo p new Foo use p delete p p NULL 这是由答案和评论 https stackoverflow com questions 19
  • 用泛型类型替换模板化函数指针

    我写了以下包装std bind and std queue include Queue h template
  • 将 const 关键字添加到作为参数传递给函数的数组

    有什么办法可以添加吗const作为参数传递给函数的数组的关键字 void foo char arr arg 如果我放置const before char void foo const char arr arg 或之后char void fo
  • 段寄存器如何参与内存地址转换?

    到目前为止我所学到的有关细分的知识 虚拟地址包含段选择器和偏移量 段选择器与GDTR配合使用 查找段描述符的线性地址 段描述符保存有关所选段的信息 包括其线性地址 所以 我的问题是 根据我所读到的内容 虚拟地址被加载到段寄存器中 然后以某种
  • 如何在 MOS 6502 的 asm 中创建延迟

    我是 ASM 新手 我正在尝试研究如何为以下代码创建延迟 org 1000 loop inc d021 jmp loop 我想评论已经足够清楚了 每帧更改颜色的代码示例 1 50 秒 sei enable interrupts loop1
  • 该程序如何知道该字符串存储的确切位置?

    我用 Radare2 反汇编了一个 C 程序 在这个程序中有很多调用scanf像下面这样 0x000011fe 488d4594 lea rax var 6ch 0x00001202 4889c6 mov rsi rax 0x0000120
  • 内存映射图形输出

    我正在探索使用内存映射图形绘制像素和线条 我在 Windows 的 Textpad 中使用 TASM 当我单击 运行 时 整个屏幕变成蓝色 就是这样 没有绘制像素 model small stack data saveMode db xVa
  • __stack_chk_fail_local 和 -fno-stack-protector - 如何让它工作?

    Update 我刚刚发现问题出在我的项目 libxml2 中包含的预构建库上 它是在启用堆栈保护的情况下构建的 因此依赖于 stack chk fail local方法 我现在已经重建了该库 fno stack protector也是 一切
  • 查找用户输入中的第一个和最后一个大写字母

    输入将从 a z 或 A Z 中获取 并且输入以星号结束 我们需要将输入字符的第一个和最后一个大写字母作为输出 另外 我们应该显示每次输入的内容 注意 我们逐个字符地获取输入 而不是作为字符串 测试用例1 输入 aAbCcP 输出 AP 测
  • 在汇编中,指令指定数据类型吗?

    我是汇编语言编程 x86 的初学者 以下说法是否正确 在汇编中 BYTE WORD DWORD 等数据类型分别表示 8 位 16 位和 32 位模式 而不仅仅是整数 它们本身没有意义 它们只是位模式 使用它们的指令赋予了它们意义 汇编 代码
  • 删除指向对象的 C++ 指针

    我认为删除命令会释放我分配的内存 有人可以解释为什么删除后我似乎仍然有内存在使用吗 class Test public int time int main Test e e new Test e gt time 1 cout lt lt e
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考

随机推荐