【问题标题】:MOV Instruction for Registers寄存器的 MOV 指令
【发布时间】:2016-02-18 02:58:35
【问题描述】:

所以我正在使用 Visual Studio 使用 C++ 运行 _asm。

所以我是汇编编程的新手,我正在学习一本教科书,并且知道通用寄存器 EAX 保存 32 位,AX 为 16,AL,AH 为低/高。

那么我将如何仅使用 MOV 指令来移动多个命令。我试过做

MOV AL, 'a', 'c' , 'e'

但是我得到了非法数量的操作数。那只有 3,所以 AL 不应该能够保持这个值吗?

我做了之后尝试

MOV EAX, 0
MOV AL, 'a', 'c' , 'e'

那么我如何将三个不同的值甚至更像 12 个字母移动到 8 位?我不应该移动 0 来清除 8 位的低位和高位,从而允许移动这 3 个变量吗?我只想使用 8 位寄存器将多个值移入其中,在本例中为 3。此外,我想知道如何将 12 个字母放入 8 位中。我读到你会做 MOV EAX, 0 但我没有运气。

注意:这不是完整的程序,我只包含了 MOV 的问题。

#include "stdafx.h"
#include "stdio.h"
#include <iostream>

using namespace std;
using std::cout;
using std::cin;


int main(void)
{

    char test
    _asm
    {
        MOV EAX, 0
        MOV AL, 'a', 'c' , 'e'
    }
}

【问题讨论】:

  • 你试过mov eax, 'ace'吗?
  • 内联 asm 不是学习 asm 的最佳选择,IMO。 stackoverflow.com/tags/x86/info 标签 wiki 中有一些建议。 mov 不能采用多个源操作数。您可以让汇编器进行数学运算以生成直接源操作数的值,但语法类似于mov eax, ( 'a' &lt;&lt; 16 | 'c' &lt;&lt; 8 | 'e' )。 (或类似的东西)。请注意,它是具有整数值的单个表达式。你认为 12 个字母怎么能适合 8 位呢? ASCII 字符是 8 位。
  • 我的一部分认为您真的希望使用指向包含字符串并设置字符的内存的指针。
  • 由于不清楚他希望如何将字节填充到 EAX 中,以便在 EAX 中获取 0x61636500,您可以使用 mov eax, 'ace\0' 。如果您希望 MSB 为零 (0x00616365 ),则可以使用 mov eax, 'ace' 最初由 Mr Oblivious 建议的
  • @PeterCordes 因为 MASM 语法是 Visual Studio C++ 的一部分,所以我提供了这个示例代码来通过内联汇编器演示 MASM 语法。同样的事情也适用于纯 MASMrextester.com/edit/JXH99489

标签: c++ assembly cpu-registers mov


【解决方案1】:

如果您只有文字可以推入 EAX,您可以使用以下代码:

MOV EAX, 'ace'

如果您想要一段代码可以使用三个变量来组成 EAX 上的值,请使用以下代码作为模板并将文字替换为变量名。

MOV EAX, 'a' * 0x10000 + 'c' * 0x100 + 'e'

最后,如果您想要一个逐个字符推送的解决方案,您可以使用以下方法:

void init()
{
    _asm
    {
       XOR EAX, EAX
    }
}

void push(char c)
{
    _asm
    {
        SHL EAX, 8
        MOV AL, c
    }
}

我还想知道如何将 12 个字母变成 8 位。我读 你会做 MOV EAX, 0 但我没有运气。

我不明白你的意思,你的意思是 EAX 中的 12 个字符。 EAX 是 32 位的,这意味着只有 4 个 ASCII 字符。但是,如果您试图将其放入 EAX 中的是十六进制数字(0-9 和 a-f),这意味着您不能再将其中的 8 个放入 EAX。

【讨论】:

  • 这需要shl eax, 8 才能移动一个完整的字节。您是否混淆了'a' (0x61) 和0xa?即便如此,你还是想要xor eax, eax/mov al, 0xa/shl al, 4/or eax, 0xc/shl eax, 4/or eax, 0xe。 (这应该避免 Intel CPU 上的任何部分寄存器减速。您的序列在第二个shl 上的前 IvB 硬件上存在部分寄存器停顿或合并 uop,因为第一个 shl 删除了高位清除标记用除零习语以外的东西写完整的寄存器)
  • 你的mov eax, imm32 第一个版本也有同样的问题:试试'a' * 0x10000 + 'c' * 0x100 + 'e'。每个 ASCII 字符占用一个完整字节(两个十六进制数字,也就是半字节)
  • 谢谢彼得,完全错过了,出于某种原因假设它是一个十六进制数字而不是一个完整的字符。我的答案是相应的。
  • 首先我不知道 'ace' 等价于 ('a' MOV EAX, 'ace' 可能是他/她所追求的。
  • @Michael,我阅读了您对 OP 的评论,如果您试图让 EAX 指向文字字符串“ace”,这是另一回事,而 'ace\0' 不一样。可能你已经知道了,但我只是确定一下。
猜你喜欢
  • 1970-01-01
  • 2011-05-04
  • 2015-11-01
  • 2019-09-12
  • 2023-04-02
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多