【问题标题】:X86 inline assembly, writing into C arrayX86 内联汇编,写入 C 数组
【发布时间】:2010-10-31 18:31:44
【问题描述】:

程序集信息:使用 Visual Studio 2010 编写嵌入到 C 中的内联程序集

你好, 我正在尝试在 C 中写入一个字符数组并尝试模仿此 C 代码的操作:

resNum[posNum3] = currNum3 + '0';

目前这是我所拥有的:

mov ebx, posNum3; 
mov resNum[ebx], edx; //edx is currNum3
add resNum[ebx], 48; // add 48 because thats the value of the char '0'

我也试过这样做:

mov ebx, posNum3;
mov   eax, resNum[ebx] ;// eax points to the beggining of the string
mov eax, edx; // = currnum3
add eax, 48; // + '0'

没有任何运气,非常感谢您的帮助!

【问题讨论】:

    标签: arrays visual-studio-2010 assembly x86 inline-assembly


    【解决方案1】:

    问题是指令

    mov resNum[ebx], edx
    

    将 4 个字节(整个 dword)移动到目标,而不是单个字节。你可能想要

    mov byte ptr resNum[ebx], dl
    

    相反。虽然汇编器允许您省略地址上的“size ptr”前缀,但您可能不希望这样做,因为弄错会导致很难看到错误。

    【讨论】:

      【解决方案2】:

      我的 X86 asm 生锈了,但是... 如果您使用的是字符(8 位),您首先需要在开始循环之前将 EAX 清零,然后将字符移动到 AH 或 AL 中,例如:

      ;在开始循环之前 异或 EAX, EAX ;如果您确定不会通过添加 48 来溢出 8 位数字,这可以超出循环 ; ...代码在这里设置循环 mov EBX, posNum3 mov AL, resNum[EBX] 添加 AL, 48 ; ...循环的其余部分

      请注意,编译器会比您做得更好...除非您是 Mike Abrash 或像他这样的人 :)

      【讨论】:

        【解决方案3】:

        避免使用像

        这样的表达式
        mov resNum[ebx], edx;
        

        因为你永远不知道resNum 是什么。可以是esp + 4这样的表达式,而mov [esp + ebx + 4], edx没有操作码,所以改用小步。

        另外,ebx 是一个必须在调用之间保留的寄存器。请参阅http://msdn.microsoft.com/en-us/library/k1a8ss06%28v=VS.71%29.aspx 了解详细信息并了解调用约定。

        【讨论】:

          【解决方案4】:

          大部分内联汇编器允许使用name 而不是size ptr [name],所以你可以直接写

          mov al, currNum3
          add al, 0x30 //'0'
          mov edx, posNum3
          mov ecx, resNum
          mov byte ptr [edx+ecx], al
          

          如果 resNum 是全局数组,而不是函数参数或局部变量,则可以编写更短的代码:

          mov al, currNum3
          add al, 0x30 //'0'
          mov edx, posNum3
          mov byte ptr [resNum+ecx], al
          

          【讨论】: