With the Doukutsu Assembler's labeling system, you can make jump instructions jump to a label instead of a numerical address.MOV ECX,[EBP+8] CMP EDX,6 JGE :downhere ;you can jump to labels in your code. XOR EAX,EAX MOV [ECX+74],EAX :downhere PUSH 600 PUSH 0 CALL 40F350 ADD ESP,8 MOV ECX,[EBP+8] JMP 40488A ;or you can jump to addresses. NOP NOP NOPRemember that all labels must start with a colon (:). You can use an instruction in the form JMP :examplelabel to jump to wherever :examplelabel is located in your code. The reason labels start with a colon is to prevent any hexadecimal confusion. The instruction JMP :ABCD means "jump to the label with name ABCD", but JMP ABCD means jump to the address 0xABCD. IMPORTANT: Labels are not case-sensitive. That means the label :suesakamoto is the same as :SueSakamoto, which is also the same as :SUESAKAMOTO. In fact, no matter what you're doing, all your code is considered case-insensitive (Like add esp,20 and ADD ESP,20 are the same thing). For more information, refer to the syntax guide. Types of Jumps
The above table shows the types of jumps currently supported by the Doukutsu Assembler. The synonyms of those jumps are supported as well. For all intents and purposes, a CALL is considered a jump, and you can even use labels with calls, such as CALL :labeled_function. Switch Statements Because switches are so common in NPC and Weapon hacking, the Doukutsu Assembler does accept many different kinds of switch statements. Six common examples are shown below. JMP [EAX*4+(address)] JMP [ECX*4+(address)] JMP [EDX*4+(address)] JMP [EAX*4+:labelname] JMP [ECX*4+:labelname] JMP [EDX*4+:labelname]Where either (address) or :labelname refers to the place where the switch table begins. You can still make more complicated statements than these simple switches. For example, to create some sort of multi-table switch statement, use a command like JMP [EAX*4+ECX+:labelname]. The Print Command The command in the form of print :labelname will insert the address of the label :labelname as little-endian hex data into the code. This is best used in conjunction with switch statements. For example, let's assume you're designing a custom NPC with 4 unique ScriptStates: offset 43C8E0 PUSH EBP MOV EBP,ESP SUB ESP,50 // pretend there are framerects // being declared here. MOV EDX,[EBP+8] MOV EAX,[EDX+74] ;Grab scriptstate JMP [EAX*4+:switchtable] :state0 // pretend that there is // a bunch of // code here. :state1 // pretend that there is // a bunch of // code here. :state2 // pretend that there is // a bunch of // code here. :state3 // pretend that there is // a bunch of // code here. MOV ESP,EBP POP EBP RETN :switchtable ;Our table of addresses. print :state0 ;this will be replaced with the address of :state0, little-endian style. print :state1 print :state2 print :state3File: label_dump.txt Every time you assemble a hack, the labels in your assembly source-code will get converted to real numerical addresses. If you want to see the actual address of each label you used, just look in (Filename)_label_dump.txt after assembling. Labels in Non-Jump and Non-Call Instructions Starting with version 1.0, you can now use labels in commands that are not jumps and also not calls. Each label is simply translated into a 32-bit hex number. So if you use CMP ECX,:myLabel, and :myLabel has the address 0x401007, then you would be comparing ECX with 401007. Here's an example of how you can use labels to store a predefined 32-bit value into EAX: offset 43B005 MOV EAX,DWORD [:this_is_a_constant] PUSH EAX //EAX holds the constant 0x600DFACE CALL :some_function ADD ESP,4 RETN INT3 INT3 :this_is_a_constant data CE FA 0D 60 //Little endian 0x600DFACE INT3 INT3 INT3 INT3 :some_function PUSH EBP MOV EBP,ESP //Pretend there is code here. MOV ESP,EBP POP EBP RETNOf course, the above code has no practical purpose because you could just do PUSH 600DFACE. I just gave this example to illustrate another way you could potentially use labels. Table of Contents |