【问题标题】:Pointers in assembly language汇编语言中的指针
【发布时间】:2013-02-08 14:05:00
【问题描述】:

我正在尝试了解如何在程序集中使用指针。通过阅读一些有关内部的教程,我认为已经了解了一些概念。但是当我去尝试它时,它确实有效。下面是一些将 C 转换为 ASM 的尝试。

C

const char *s = "foo";
unsigned z = *(unsigned*)s;
if(!(z & 0xFF))
do_something();
if(!(z & 0xFFFF))
 do_b_something();

(这里不是完整的代码,但它是一个字检查,因此,还有两个分别检查0xFF0000,0xF000000的stmts。

ASM:

mov ebp,str
mov eax,ebp

mov eax,[eax]
and eax,0xFF
cmp eax,0
je etc

mov eax,[eax]
and eax,0xFFFF
cmp eax,0
je etc

它返回一个段错误。

然后尝试:

mov eax,dword ptr [eax]

这是由 gcc 编译器生成的,你可以在其他一些程序集代码中看到它,返回

invalid symbol

在 FASM 汇编器上。 FASM 并不真正支持它,还是我遗漏了什么?

【问题讨论】:

  • dword ptr 是 MASM 所需要的,其他的不多。只需使用普通括号。段错误可能是由于在销毁它后使用eax 作为指针。提示:使用test
  • 我不会说 C - 你能解释一下你想要达到的目标吗?我有一种感觉,组装起来很简单。

标签: linux assembly x86 32-bit fasm


【解决方案1】:

我认为这就是你想要做的:

    mov  ebp,str
    mov  eax,ebp

    mov  ebx,[eax]
    test ebx,0xFF
    jz   low_byte_empty

    do_something:
         ; some code here...

low_byte_empty:
    test ebx,0xFFFF
    jz   low_word_empty

    do_b_something:
         ; some code here.

low_word_empty:

解释:

首先,正如 JasonD 在他的回答中已经提到的那样,您正在加载指向 eax 的指针,然后对其执行逻辑 and,然后您仍在使用 eax 中的结果来寻址内存(一些内存在0x0 ... 0xFF 范围内的偏移量。

那么你的代码出了什么问题:你不能在同一个寄存器中同时保存一个指向内存地址的指针和一个值。所以我选择将[eax]的值加载到ebx,你也可以根据需要使用一些其他的32位通用寄存器(ecxedxesiedi)。

然后,您不需要使用cmp 来检查寄存器是否为空,因为cmp 所做的只是它进行减法并设置标志。但是and 已经设置了 ZF(零标志),所以这里绝对不需要cmp。然后,由于这里不需要cmp,我们也不需要结果,我们只想更新标志,最好使用testtestand 执行完全相同的逻辑 AND,唯一的区别是 test 不存储结果,它只更新标志。

【讨论】:

  • 真的!我不需要cmp。 and 改变了目标值,我忘记了一段时间,所以,我永远不会得到预期的结果!我之前解决的 EAX 错误。非常感谢。
  • 您还可以通过注意 test ebx,0xff 与 test bl,bl 相同,并且 test ebx, 0xffff 与 test bx, bx 相同来从这个答案中挤出额外的性能和字节.最后,您可能希望使用 ECX 或 EDX 之类的寄存器而不是 EBX,因为 EBX 通常应通过函数调用保留。
【解决方案2】:

根本不清楚您在原始代码中要做什么 - 看起来不正确。

但是:

mov eax,[eax]
and eax,0xFF
cmp eax,0
je etc

mov eax,[eax]

不会工作。您正在用存储在 EAX 中地址的值覆盖 EAX 的内容,操作该值,然后尝试在分支后重新加载它而不恢复原始指针。

【讨论】:

    【解决方案3】:

    以下变体更简单、更小、更快并且只使用一个寄存器。

        mov  eax, str
        mov  eax,[eax]
    
        test al, al
        jz   low_byte_empty
    
    do_something_byte:
         ; some code here...
    
    low_byte_empty:
         test ah, ah
         jz   low_word_empty         
    
    do_something_word:
         ; some code here
    
    low_word_empty:
    

    【讨论】:

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