1

我试图了解如何在程序集中使用指针。通过阅读一些有关内部的教程,我认为已经了解了一些概念。但是当我去尝试它时,它确实有效。下面是一些将 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 并不真正支持它,还是我遗漏了什么?

4

3 回答 3

1

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

然而这:

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

mov eax,[eax]

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

于 2013-02-08T14:09:37.463 回答
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)。

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

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

于 2013-02-08T15:50:24.693 回答
0

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

    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:
于 2013-02-09T08:12:09.047 回答