【问题标题】:I don't understand these assembly code and machine code differences if assembly code instructions are equivalent of machine code instructions如果汇编代码指令等同于机器代码指令,我不理解这些汇编代码和机器代码差异
【发布时间】:2016-04-15 02:59:16
【问题描述】:

有人说汇编语言=机器语言,只是我们在汇编语言中使用助记符。

读了 Petzold 的《CODE》,我还是不明白有些汇编代码是怎么翻译成机器码的。

例如(来自 Tutorials Point 的组装课程):

_start:             ;tells linker entry point
   mov  edx,len     ;message length
   mov  ecx,msg     ;message to write

section .data
msg db 'Hello, world!', 0xa  ;our dear string

我的理解是 msg 包含“Hello, world!”它已移至 ECX。

但据我所知,在 x86 中,ECX 只能存储 32 位。

那么我们如何移动“Hello, world!” - 超过 32 位 - 到 ECX 中?

那部分的等价物是什么

section .data
msg db 'Hello, world!', 0xa  ;our dear string

在机器码中?

【问题讨论】:

    标签: assembly executable


    【解决方案1】:

    据我了解,命令

    mov ecx,msg
    

    实际上并没有将整个字符串 Hello, world! 移动到寄存器中,而是将指针移到它的开头。汇编指令

    msg db 'Hello, world!', 0xa
    

    显然定义了一个包含实际字符串Hello, world! 的内存位置,并且可以通过标签msg 引用。但是,实际使用情况有点难以判断,因为缺少对寄存器内容的进一步使用。

    【讨论】:

    • 那个汇编代码假定“Hello world”字符串已经在内存中?字符串从 0xa 开始?但是这个汇编代码是如何翻译成机器代码的。 section .data msg db 'Hello, world!', 0xa 。我的意思是它的“机器代码”版本是什么?
    • 据我了解,字符串实际上并未转换为机器码。汇编器显然会生成一些二进制文件,其中包括翻译后的代码和一些原始数据,这些原始数据也包含在二进制文件中,可以在汇编文件中定义。
    【解决方案2】:

    使用msg db,您可以定义包含字节字符串序列的地址。使用mov ecx, msg,您只加载此地址而不是其内容。然后可以通过加载[ecx]、[ecx+1]等来加载字符串

    .data 定义程序部分。 .text 通常包含机器码、.data 可修改的程序代码。它们可以有更多,例如异常处理标签等。

    【讨论】:

      【解决方案3】:

      你的问题很好。它涉及间接的基本计算机概念。

      计算机处理诸如“Hello, world!”之类的文本字符串的正常方式就是将它作为一系列字符保存在内存中。例如:

      Memory address    Memory contents
      8201              'H'
      8202              'e'
      8203              'l'
      8204              'l'
      8205              'o'
      8206              ','
      8207              ' '
      ...               ...
      820E              0
      

      本例中msg 的值为0x8201。不是'H'。因此,值 0x8201 被移动到寄存器ecx

      稍后,任何想要该消息的人都可以从ecx中读取0x8201,然后到内存地址0x8201找到实际文本消息的开头。这有意义吗?

      【讨论】:

      • 但是这个汇编代码是如何翻译成机器码的。 section .data msg db 'Hello, world!', 0xa 。我的意思是它的“机器代码”版本是什么?
      • 是的,我明白了你的问题。它的答案很微妙,不容易掌握。内存模型需要一些时间来适应。 section .data 本身并不生成机器代码,而是配置汇编器以供您进一步使用。 db 'Hello, world!', 0xa 只是生成我上面描述的字节串。您还没有告诉汇编程序将该字符串放在内存中的哪个位置,因此它选择了一个位置,例如地址 0x8201。然后符号msg 代表地址(只是一个数字)0x8201。这都是象征性的,需要一些思考。祝你好运。
      • 知道了。因此,并非所有用汇编代码编写的东西在机器代码中都具有直接等价性。
      【解决方案4】:

      语法取决于汇编程序,对于 MASM 或 ML(微软的 MASM 版本),语法为

              mov     ecx,offset msg    ;ecx = offset (address) of msg
      

      这清楚地表明 msg 的偏移量或地址正在加载到 ecx 中,而不是 msg 的前 4 个字节。

      【讨论】:

        【解决方案5】:

        对于 x86,英特尔的 insn 参考手册列出了每条指令的所有编码(请参阅https://stackoverflow.com/tags/x86/info 中的链接)。

        mov ecx, msgmov r32, imm32 编码。 msg 的地址最终会在链接时填充到指令中的这 4 个字节中,因为那是确定最终绝对地址的时候。

        mov ecx, [msg] 将是从绝对地址(msg 的开头)加载的 4 字节。它将被编码为mov r32, r/m32,对源使用内存操作数编码。

        len 可能是用 equ 汇编指令定义的。所以它是一个符号,但它的值不是地址。相反,它的值是 asm 源文件中的一个数字。 msg是一个符号,也是一个标签,其值一个地址。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多