1

I am trying to understand how to use pointer in assembly. By reading some tutorials around internel,I think had undertantood some concepts. But when I'II go to try it,it did work. Below some attempts to translate C to ASM.

C

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

(here's not full code,but it's a word-check,thefore,there is more two stmts which checks 0xFF0000,0xF000000 respectivily.

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 

It returns a seg fault.

And the try:

mov eax,dword ptr [eax] 

that's generated by gcc compiler and you can see it in some other assemblies code,returns

invalid symbol

on FASM assembler. It isn't really supported by the FASM or am I missing something?

2
  • dword ptr is needed by MASM and not much else. Just use the plain brackets. The seg fault is likely due to using eax as pointer after destroying it. tip: use test Commented Feb 8, 2013 at 14:09
  • I don't speak C - could you provide some explanation what you are trying to achieve? I have a feeling that in assembly it is very simple. Commented Feb 8, 2013 at 15:09

3 Answers 3

1

I think this is what you are attempting to do:

 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: 

Explanation:

First, as JasonD already mentions in his answer, you are loading a pointer to eax, then doing a logical and to it, then you are using the result still in eax to address memory (some memory offset in the range 0x0 ... 0xFF).

So what goes wrong in your code: you can't keep in the same register both a pointer to a memory address and a value at the same time. So I chose to load the value from [eax] to ebx, you can also use some other 32-bit general register (ecx, edx, esi, edi) according to your needs.

Then, you don't need to use cmp to check if a register is empty, because all cmp does is that it does the subtraction and sets the flags. But ZF (zero flag) is already set by and, so cmp is absolutely unnecessary here. Then, as cmp is not needed here and we do not need the result either, we only want to update the flags, it's better to use test. test does exactly the same logical AND as and does, the only difference being that test does not store the result, it only updates the flags.

Sign up to request clarification or add additional context in comments.

2 Comments

Really! I don't need cmp. The and changes the destination value,and I forgot it for a period,so,I never will get the expected result! the EAX error I had solved before. Thank you so much.
You can also squeeze extra performance and bytes out of this answer by noting that test ebx,0xff is the same as test bl,bl, and that test ebx, 0xffff is the same as test bx, bx. Finally, you might want to use a register like ECX or EDX rather than EBX, because EBX should normally be preserved over a function call.
1

It's not at all clear what you're trying to do in the original code - doesn't look right.

However this:

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

Isn't going to work. You're overwriting the contents of EAX with the value stored at the address in EAX, manipulating that value, and then trying to reload it after the branch without restoring the original pointer.

Comments

0

Following variant is simpler, smaller, faster and uses only one register.

 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: 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.