Assembly primer

Aug 29, 2006 at 3:08 PM
Junior Member
"Wahoo! Upgrade!"
Join Date: Jul 14, 2006
Location:
Posts: 47
Well, I did a few searches for "rects" or "boundaries", but didn't turn up much ( I'm looking to extend the boundaries for the main character sprite). But I did find something by accident in this thread. It seems that "push" puts in the co-ordinates to which something, such as the Air counter in that thread, or the textbox. "call" seems to bring forth the Air counter or the textbox, but I'm not clear on the others, such as the "add esp" or the "mov". I've only had a brief look at it though, and'll probably try to figure out more of it.
 
Aug 29, 2006 at 4:46 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
Nice work. Rather nice work, in fact, for someone who doesn't know assembly. ;)

First off, you'll NEVER find any strings or high-level structures in assembly. Text is generally going to be referenced to by an offset into memory. An structures are jut stored in memory using conventions, not schemantics managed by the language.

push adds a value ontop of the stack. This is usually used to pass parameters to a function. FThe function is called by, well, "Call" and the offset where the code is stored. So if you had a function at offset X with 2 parameters, 5 and 10, you'd do this...

push 0x0A
push 0x05
call X
 
Aug 29, 2006 at 5:38 PM
Junior Member
"Wahoo! Upgrade!"
Join Date: Jul 14, 2006
Location:
Posts: 47
RuneLancer said:
Nice work. Rather nice work, in fact, for someone who doesn't know assembly. :)

First off, you'll NEVER find any strings or high-level structures in assembly. Text is generally going to be referenced to by an offset into memory. An structures are jut stored in memory using conventions, not schemantics managed by the language.

push adds a value ontop of the stack. This is usually used to pass parameters to a function. FThe function is called by, well, "Call" and the offset where the code is stored. So if you had a function at offset X with 2 parameters, 5 and 10, you'd do this...

push 0x0A
push 0x05
call X

So if I wanted to increase the MyChar image parameters, i'd have to find the following:

push 0x0F
push 0x0F

and change it to something larger, such as:

push 0x18
push 0x18

And I'm guessing there wouldn't be a call funtcion here, seeing as the main character isn't something like the Level Up above your head.

Edit
Code:
010853 add esp,0x08	83 C4 08 ; Move the stack pointer back

1) Is this an add function, which adds units to another...thing/unit. Or is it a move function. I'm guessing the former, and if so...
2) Can this function add any unit to something, such as a unit of experience or health?
 
Aug 29, 2006 at 7:12 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
The "esp" part of the command (one of its "operands") is called a register. There are a few of these (eax, ecx, edx, ebx, esp, ebp...) They're the unit of data the processor works with. A register is like a temporary variable. Esp in this case is a pointer into the stack. We're ading 8 to it with this command because we pushed 2 values on the stack beforehand (your processor is a 32bit processor, meaning each value is 32 bits in size, so that's 4 bytes times 2, 8)

I really look forward to posting my primer. :) A lot of this stuff is covered in it. 'Course, no primer means no reference material to figure out this stuff, but I'm glad to see I'm covering stuff that's useful...

Have a look at the NPC guide I posted in the NPC thread. Quote's sprite is more or less handled the same way as the entities are. It places a series of rects (actually 4 32-bit values) in local space and picks on to copy to a sprite structure (again, a series of 32bit values - we KNOW it represents a sprite, but nothing explicitely says so in the code). I don't know where Quote, specifically, exists and is drawn, mind you, but it shouldn't be too hard to look for it.

Edit: to answer your question, add can be used to add two things together, yes. But the first parameter (its first "operand"), which receives the result, must be a register, offset, or similare - it can't be a value (0x08, for instance.)
 
Aug 29, 2006 at 9:15 PM
Junior Member
"Wahoo! Upgrade!"
Join Date: Jul 14, 2006
Location:
Posts: 47
I seem to be reading your last few posts about ten times before actually understanding them fully. :) At least I'm getting them.

Have a look at the NPC guide I posted in the NPC thread.

Alas, the link has expired. i could have sworn I took a look at that at some point, but a search turned up nothing. :(

Being the regular idiot that I am, I got thinking that the hex for 16 was 0F. No. It's 10. A search of that came up with...
Code:
00487A72 FF 75 F0					push [ebp-0010]
00487A75 FF 75 10					push [ebp+0010]

It might be something completely wrong, but it matches what I'm searching for. The only other search came up with:

Code:
00487B54 FF 75 F0					push [ebp-0010]
00487B57 57						push edi

So I don't think that's it.

I'm about to test it, so I'll edit this post to let you all know.

Edit:
No, failure. I don't know what it did, but I didn't stick around to find out. I kept a backup copy, so it's all good. However. The reason I think it failed was because I missed the

Code:
push [ebp-0008]

Before those commands. This makes me almost certain that i'm looking for the wrong register command, but, well, I have no idea.

Edit2: That shouldn't be a register command, should it? It's not a temporary variable, so there shouldn't be any need for the [ebp+0x10], it should just be push 0010, or even push 10? There has to be a command around linking it to the fact that there are however many sprites in the MyChar, but i don't know whether that would be a pointer, or a figure.
 
Aug 30, 2006 at 3:22 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
A pointer is a value which represents an address. When accessing a pointer, the processor takes the address stored in the pointer and gets the value there. You'd want to have a pointer to, for instance, remove a sprite from a list. You can just pass the sprite's address and have the function handle it like a pointer, setting the value at that address to 0. It's FAR more efficient than telling it to go unset sprite 152 and having a lea instruction calculating an offset into the sprite table and the sprite structure to find the "off" switch for that sprite. Hopefully that clears that up.

The ebp register is used to point to data. Generally, it'll be set to wherever the stack points to (mov ebp,esp) and will have a certain value added or removed from it to move it around according to where it needs to pick data when it reserves memory locally. After the function, the locally-reserved memory is cleared by restoring the old value with a pop instruction.

The addressing mode used here treats ebp as a pointer (that's why there are square brackets around it) but also adds or subtracts from the address stored in it. For instance, if ebp is offset 4856A7 and we add 0x10 to it, we have 4865B7 and since it's a pointer, we check its value.

Indirect addressing occures when you have a structure usually. Your register would hold the base offset of the structure and you'd access the data in it by indirectly referencing it (ie, the 10th byte contains the enemy's health, so, [ebp+0A]) It can also be used to access local memory, which is usually the case when we use ebp. So the things you posted are for locally-stored data.

Games hardly ever hardcode their data in the code directly. So you shouldn't expect to find the size directly stored in the middle of an instruction. In fact, there's no such thing as size - it's very unflexivble and inefficient to have a fixed size. Pixel stored a bounding rect instead. Each rect is 4 sides with 4 bytes each, meaning a frame is 16 bytes. This is pushed into local space in the appropriate function. You will never find 0x10 in relation to Quote's size. You'll have to find the real chunk of code which manages his sprite, and edit that.

Edit: Something I forgot. USUALLY, when you see an operand like [ebp+08] it means it grabs the 32bit value 8 bytes from the start of the stack (so that would be the 2nd parameter, the 1st often being the return address, which you can safely ignore.) When it's subtracted from the register (ie, [ebp-3C]) this is usually stuff in local space. You'll see something like this at the start of most functions...

push ebp ; Back up ebp
mov ebp,esp ; Make ebp point to the top of the stack
sub esp,0x?? ; Allocate ?? bytes above the stack. Bytes which we'll scrap after the function.
...
pop ebp ; Restore ebp. The local data is now lost, as it is useless.
ret ; Return to whatever called the function.

Hopefully that clears up a few things on indirect addressing and the stack (a push instruction will move the stack pointer by 4 bytes after dropping the value on top of the stack, and pop does the opposite, putting the value it just removed from the top of the stack into the operand (such as a register (eax, ecx...) or an offset ([0049ACB9]...), or even an indirect reference ([eax+08]))
 
Aug 30, 2006 at 7:14 PM
Junior Member
"Wahoo! Upgrade!"
Join Date: Jul 14, 2006
Location:
Posts: 47
OK, I think I need to stop thinking for a while. My head hurts.

Gah, I hate this. I guess tring to find something this complicated isn't really a good thing for a beginner. I'm getting the hang of the commands though, so I just need to work out other ways to find the boundaries. For example, I could find the EQ functions and the Mimiga Mask EQ, then trace it back to the data of the sprites.

Either that's a valid way, or I'm completely wrong.
 
Aug 31, 2006 at 6:06 PM
The Bartender
"All your forum are belong to us!"
Join Date: Jun 18, 2006
Location: Montreal, Canada
Posts: 581
Age: 40
It's not an invalid way, but it's not going to be any easy. You might have more luck looking for an actual bit of code which sets the frames. Chances are the game will set a flag for future use when it checks for the mimiga mask.

What you want to do is start by getting a foothold in the code. The best way to do this is to try to find what a few offsets hold and to work off of those.

Another trick is to find a simple, generic function and to figure out what it does. Something that doesn't use offsets if possible. An example of this would be a function that takes two offsets, a physical offset into the executable and a logical offset in RAM, and loads a string from the exe to RAM. Then, once you've figured out the function does that, you can look for calls to it and figure out that "this" call loads the menu text, and "that" call loads such other text, and work from there.

It takes some guesswork at first and a lot of experimenting. But once you have your foothold in the file, it's a real joke to find anything. :)
 
Jun 21, 2007 at 5:53 PM
Senior Member
"This is the greatest handgun ever made! You have to ask yourself, do I feel lucky?"
Join Date: Apr 14, 2006
Location:
Posts: 112
Jun 21, 2007 at 6:11 PM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Mar 9, 2007
Location:
Posts: 170
I was wondering the same thing just a few days ago.
Not that I think I'd be able to make any use of them, but I'm curious and want to have a look.

So, yeah, any of you old veterans have 'em?
 
Jun 21, 2007 at 6:21 PM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: he/him
Orfvar Stöhtkonung said:
I was wondering the same thing just a few days ago.
Not that I think I'd be able to make any use of them, but I'm curious and want to have a look.

So, yeah, any of you old veterans have 'em?

Well for its use: You can patch the games actual assembler code with it, also disassembly was in there.
 
Oct 19, 2007 at 2:16 AM
Senior Member
"Wahoo! Upgrade!"
Join Date: Jul 14, 2007
Location:
Posts: 65
Back
Top