如何获取变量的地址并在 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 程序集中取消引用它? 的相关文章

  • 动态分配对象数组

    我有一个包含动态分配数组的类 例如 class A int myArray A myArray 0 A int size myArray new int size A Note that as per MikeB s helpful sty
  • 取消的分支与常规分支有何不同?

    特别是对于 SPARC Assembly 取消的分支与常规分支有何不同 我一直认为 当我需要填充分支指令的 nop 延迟槽时 需要取消分支指令 但是 我认为我在这一部分上是不正确的 因为您可以在不取消分支的情况下填充 nop 如果不采用分支
  • 将两个 32 位整数向量相乘,生成 32 位结果元素向量

    将每个 32 位条目乘以 2 的最佳方法是什么 mm256i互相注册 mm256 mul epu32不是我正在寻找的 因为它产生 64 位输出 我想要每个 32 位输入元素都有一个 32 位结果 而且 我确信两个 32 位值的乘法不会溢出
  • 为什么不能执行 mov [eax], [ebx] [重复]

    这个问题在这里已经有答案了 我可以做这个 mov eax ebx 和这个 mov eax ebx 甚至这个 mov eax ebx 但不是这个 错误C2415 mov eax ebx 只是wtf 为什么 它与 ptr1 ptr2 相同 为什
  • 如何在汇编语言中换行打印多个字符串

    我试图在汇编中的不同行上打印多个字符串 但使用我的代码 它只打印最后一个字符串 我对汇编语言非常陌生 所以请耐心等待 section text global start start mov edx len mov edx len1 mov
  • 汇编基础知识:输出寄存器值

    我刚刚开始学习汇编语言 我已经陷入了 在屏幕上显示存储在寄存器中的十进制值 的部分 我使用 emu8086 任何帮助将不胜感激 model small Specifies the memory model used for program
  • 为什么 Visual Studio 使用 xchg ax,ax

    我正在查看程序的反汇编 因为它崩溃了 并注意到很多 xchg ax ax 我用谷歌搜索了一下 发现它本质上是一个 nop 但是为什么 Visual Studio 会执行 xchg 而不是 noop 该应用程序是一个C NET3 5 64位应
  • *y++ 和 ++*y 之间的区别?

    我对这段代码将如何执行感到困惑 假设我们有 int x 30 y z y x y 和 y 和有什么不一样 该程序的输出是什么 include
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • 指向数组的指针 int (*ptr)[]

    我想了解指向数组的指针如何工作 代码片段 include
  • 确定 .NET 类型的序列化大小和非托管内存效率

    我的问题是是否可以确定引用类型的序列化大小 以字节为单位 情况如下 我使用 BinaryFormatter 类来序列化基本 NET 类型 例如 Serializable public class Foo public string Foo1
  • 两个基本的 ANTLR 问题

    我正在尝试使用 ANTLR 来获取简单的语法并生成汇编输出 我在 ANTLR 中选择的语言是 Python 许多教程看起来非常复杂或详细阐述与我无关的事情 我真的只需要一些非常简单的功能 所以我有两个问题 将值从一个规则 返回 到另一规则
  • 字符串文字在内存中的什么位置?堆栈/堆? [复制]

    这个问题在这里已经有答案了 可能的重复 C 字符串文字 它们去了哪里 https stackoverflow com questions 2589949 c string literals where do they go 据我所知 一般来
  • 在 C/C++ 中使用单个初始化来初始化具有相同值的多个指针

    我想在 C C 中使用单个赋值运算符声明两个或多个具有相同值的指针 以下代码是一个示例 List a NULL List b NULL List c NULL 一行中是否有等效项 编辑 为了澄清 我正在寻找两种语言的答案 我使用 斜杠 来区
  • 在 x86 ASM 中测试零通常哪个更快:“TEST EAX, EAX”与“TEST AL, AL”?

    测试 AL 中的字节是否为零 非零通常哪个更快 TEST EAX EAX TEST AL AL 假设之前有一个 MOVZX EAX BYTE PTR ESP 4 指令加载了一个带有零扩展的字节参数到 EAX 的其余部分 防止了我已经知道的组
  • Nasm 打印到下一行

    我用 nasm Assembly 编写了以下程序 section text global start start Input variables mov edx inLen mov ecx inMsg mov ebx 1 mov eax 4
  • 68HC11计算sin(x)的汇编代码

    68HC11 使用泰勒级数或查找表计算正弦值的汇编代码是什么 显示值只能是整数 查找表如何工作 在这种情况下 如何使用它来实现泰勒级数 http en wikipedia org wiki Taylor series 如果您正在寻找浮点解决
  • 如何在 C 中释放指向动态数组的指针?

    我用 malloc 在 C 中创建一个动态数组 即 myCharArray char malloc 16 现在 如果我创建一个这样的函数并通过myCharArray to it reset char myCharArrayp free my
  • 为什么这个函数指针赋值在直接赋值时有效,但在使用条件运算符时无效?

    本示例未使用 include 在 MacOS10 14 Eclipse IDE 上编译 使用 g 选项 O0 g3 Wall c fmessage length 0 假设这个变量声明 int fun int 这无法通过 std touppe

随机推荐