Sign in to follow this  
Crazyfool

X86 Assembly [resolved]

Recommended Posts

Hello all, I will be having a class that will entail x86 assembly code and I wanted to get a bit of a head start. I had a class that covered some but I am having difficulties getting it to work 'right'. For instance, according to: here, I should be able to access the array of characters via:
mov edx, [arrayOfLetters + 1]
in that example, I wanted to access the 2nd letter, but it doesnt matter what I put, it wont work correctly, or at least not so that I can tell. I then try displaying dl and it will give me a character completely wrong. I tested the display method via "mov dl, 'a'" and that displays fine, and I also verified that arrayOfLetters is indeed an array of characters exactly as I input it. Any help would be appreciated. [Edited by - Crazyfool on April 19, 2008 10:49:05 PM]

Share this post


Link to post
Share on other sites
EDX is a 32-bit register, you're probably moving with a DWORD PTR instead of a BYTE PTR. Try


mov dl, byte ptr [arrayOfLetters + 1]


BYTE PTR is probably automatically assumed by your assembler so you might be able to skip that.

Share this post


Link to post
Share on other sites
One thing that might help is examining assembly produced by a language you already know. For example, if you know C or C++ and use MSVC, you can get it to emit the assembly instructions for source code with the /FAs switch. If you use gcc, -S will have a similar result.

Share this post


Link to post
Share on other sites
Quote:
Original post by asp_
EDX is a 32-bit register, you're probably moving with a DWORD PTR instead of a BYTE PTR. Try


mov dl, byte ptr [arrayOfLetters + 1]


BYTE PTR is probably automatically assumed by your assembler so you might be able to skip that.


Tried that, doesn't work, and stores the value of -1 when the character should be 'O'

Share this post


Link to post
Share on other sites
I realized I should post a bit more of what I am doing:

One of the older projects I did (and didnt do too well on) used a C-style string in which we had to access and do various stuff with. I can figure out or at least try to figure out what we have to do, but I am having a lot of trouble even accessing the array.

If the array is 'p', 'i', 'e' stored in arrayPie, I would like to be access the array.

I have tried:

mov dl, byte ptr[arrayPie]
mov dl, arrayPie


and both have been unsuccessful. According to all the google pages Ive been to, that should access the first element of the array. Does it change anything if the code is in the function, or if I've pushed registers?

Share this post


Link to post
Share on other sites
You're...not doing it right. Nowhere in your code do you actually reference a memory address.

Stylistically, you should be using the SI register for the string's source index; that's what it's for. I only ever did 16-bit x86, so I don't know what it's called in 32-bit--probably ESI or something.

A bit of hideously over-commented code from a class I had which should demonstrate how to access a string (in this case, stored in "input"). It may be different in protected mode, but here goes:


mov ax,3f00h ; read from file function
sub bx, bx ; file handle 0 = keyboard
mov dx,offset input ; buffer for data read from keyboard
mov cx, 102 ; read up to 102 bytes (100 digits + \r\n)
int 21h ; execute DOS function

mov si, offset input ; get address of input buffer


"offset input" gets you the memory location of "input". And so, SI is at the head of the string. A particularity of DOS is that it'll store the \r\n at the end, so now we chop it:


add si, ax ; ax has number of bytes read from keyboard
cmp ax, 2 ; check whether a blank string was entered
je endprogram ; bail if ax = 2

sub si, 2 ; adjust for 0d0ah
mov byte [si], 0 ; replace 0d with 0 terminator
mov si, offset input ; reload si with input address


The above shows how to fiddle with the values; you simply MOV from the current SI position into a register. If I wanted to pull whatever's at the current string location into a register, it's just


mov dl, byte [si]


Does this make sense?

Quote:
One thing that might help is examining assembly produced by a language you already know. For example, if you know C or C++ and use MSVC, you can get it to emit the assembly instructions for source code with the /FAs switch. If you use gcc, -S will have a similar result.
That generally doesn't help very much. Even with optimizations off, gcc at least tends to be extraordinarily cryptic.

Quote:
Which assembler are you using? Sometimes, instructions like mov are reversed, meaning mov a,b could actually mean mov b,a in another assembler...
Er...no. Not on x86. Other things might be a bit different, but I'm almost certain that they don't arbitrarily reverse opcodes. (That wouldn't make any sense.)

Share this post


Link to post
Share on other sites
Quote:
Original post by Edward Ropple
Quote:
Which assembler are you using? Sometimes, instructions like mov are reversed, meaning mov a,b could actually mean mov b,a in another assembler...
Er...no. Not on x86. Other things might be a bit different, but I'm almost certain that they don't arbitrarily reverse opcodes. (That wouldn't make any sense.)


X86 operands are backwards in AT&T syntax. At the machine code level, most of the GP instructions have a direction bit that controls the source/dest operands (it's usually the second-to-lowest bit in the one and two-byte opcodes). Some ModRM encodings are inconsistent, too.

Share this post


Link to post
Share on other sites
Thank you for the responses:

The code for the past assignment is as:

char goCrazyBecauseThisIsSoHard( char arrayOfLetters[], int arraySize )
{
char temp;

__asm{

//I am adding this bit:
push ecx
push edx
sub edx, edx

mov edx, [arrayOfLetters]
mov temp, dl

pop edx
pop ecx
}
return temp;
}


If I put "mov edx, 'a'" then I will get 'a' correctly. Likewise, putting break points in the propgram to examine the variables will give me the arrayOfLetters[] to be the right values (in the current case, 'computer').

I tried looking over to see if I could see what was happening, but I had no luck.

You mention that I did not reference a memory address.. I am not sure exactly because this class was a bit of time ago. I am searching google but did not find anything too helpful except the link in my first post. Thank you for your time.

Edit: I am also unsure what you mean by offset input - I assume input is the name of your array/string, so in my case arrayOfLetters. Howver offset I am not so sure. The format you used gives me an error when I do mov esi, offset array

Share this post


Link to post
Share on other sites
Why are you externing to assembler? For what you're doing, there's no reason not to write it in C, and if you're trying to learn assembler you should be doing it with an actual assembler. I don't see the point, and without knowing how your C compiler is behaving it makes it really hard to actually make sense of what you're doing.

And why are you using 32-bit registers for 8-bit data?

Share this post


Link to post
Share on other sites
In the class, this is the only way I learned how to get the code at least working right. Also, this came straight from an old assignment, but I am having trouble even getting the basic stuff working.

I dont mean to be using 32 bit registers, but often if I try using the low byte to store something, I will get a size mismatch.


What I am doing is I have a C style character array that I wish to access via assembly.

Edit: this is not for a practical program or anything, that is why I am not coding this directly in C, which would be easier no doubt.

Share this post


Link to post
Share on other sites

char goCrazyBecauseThisIsSoHard( char arrayOfLetters[], int arraySize )
{
char temp;

__asm{

//I am adding this bit:
push ecx
push edx
sub edx, edx

mov edx, [arrayOfLetters]
mov dl, [edx]
mov temp, dl

pop edx
pop ecx
}
return temp;
}

Emphasis added.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this