Setting up a thread in ASM

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Zettablade
Posts: 71
Joined: Fri May 05, 2006 5:59 pm

Setting up a thread in ASM

Post by Zettablade »

So, I've gotten a chance to really toy around with mips asm on the psp. I've run into a road block of sorts though. I'm trying to write some code that loops itself forever, but it keeps crashing. What am I doing wrong? (go easy on me, I'm new to asm)

Code: Select all

	.set noreorder
	.set noat

#ifdef BUILD_V1
#include "syscallv1.h"
#else
#include "syscallv15.h"
#endif

.section .rodata.sceModuleInfo
	.global _info
_info:
	.hword 0x0000
	.byte  1, 1

	.global _start
_start:
# Create Thread
	syscall _sceKernelCreateThread
	move $a0, $v0
	move $a1, $zero
	move $a2, $zero
# Start Thread
	syscall _sceKernelStartThread
	move $a0, $zero
# Exit Thread
	syscall _sceKernelExitThread

Main:
	j Main
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Re: Setting up a thread in ASM

Post by hlide »

Zettablade wrote:So, I've gotten a chance to really toy around with mips asm on the psp. I've run into a road block of sorts though. I'm trying to write some code that loops itself forever, but it keeps crashing. What am I doing wrong? (go easy on me, I'm new to asm)

Code: Select all

	.set noreorder
	.set noat

#ifdef BUILD_V1
#include "syscallv1.h"
#else
#include "syscallv15.h"
#endif

.section .rodata.sceModuleInfo
	.global _info
_info:
	.hword 0x0000
	.byte  1, 1

	.global _start
_start:
# Create Thread
	syscall _sceKernelCreateThread
	move $a0, $v0
	move $a1, $zero
	move $a2, $zero
# Start Thread
	syscall _sceKernelStartThread
	move $a0, $zero
# Exit Thread
	syscall _sceKernelExitThread

Main:
	j Main
you need to add "nop" just after "j Main"

remember jump instructions have always a delay slot instruction they execute just before jumping at the new target, so here you need to add a nop.
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

and are you sure about your syscalls ? their arguments ?
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

hlide wrote:and are you sure about your syscalls ? their arguments ?
hlide is right :)

Let's take the SDK prototypes:
SceUID sceKernelCreateThread (const char *name, SceKernelThreadEntry entry, int initPriority, int stackSize, SceUInt attr, SceKernelThreadOptParam *option)
int sceKernelStartThread (SceUID thid, SceSize arglen, void *argp)
So, you need to have a0, a1, a2, a3, a4 and a5 for createthread, and then feed the return register (v0 in mnemonic, no? r2 in non-mnemonic :P) into the a0 of startthread, and set a1 and a2 to 0 if you don't give params.

would give something like this:

Code: Select all

.............
_start:
# Create Thread
   move $a0, _thread_name (the label of the thread name
   move $a1, _main_thread_func (the label of the function)
   move $a2, 20 (priority)
   move $a3, 4000 (stack)
   move $a4, 0 (attribute)
   syscall _sceKernelCreateThread
   move $a5, 0 (options)

# Start Thread
   move $a1, $zero
   move $a2, $zero
   syscall _sceKernelStartThread 
   move $a0, $v0
.............
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

adrahil wrote: would give something like this:

Code: Select all

.............
_start:
# Create Thread
   move $a0, _thread_name (the label of the thread name
   move $a1, _main_thread_func (the label of the function)
   move $a2, 20 (priority)
   move $a3, 4000 (stack)
   move $a4, 0 (attribute)
   syscall _sceKernelCreateThread
   move $a5, 0 (options)

.............
Adrahil : are you sure "syscall" demands a delay slot instruction as branchs and jumps do ? I never heard about. Syscall raising an exception softwarely, i'm doubtful about this demand.

Zettablade : if not, "move $a5, 0 (options)" must be before syscall. By the way, your name tells me something... DCEMU forums ?
Zettablade
Posts: 71
Joined: Fri May 05, 2006 5:59 pm

Post by Zettablade »

hlide wrote:
adrahil wrote: would give something like this:

Code: Select all

.............
_start:
# Create Thread
   move $a0, _thread_name (the label of the thread name
   move $a1, _main_thread_func (the label of the function)
   move $a2, 20 (priority)
   move $a3, 4000 (stack)
   move $a4, 0 (attribute)
   syscall _sceKernelCreateThread
   move $a5, 0 (options)

.............
Adrahil : are you sure "syscall" demands a delay slot instruction as branchs and jumps do ? I never heard about. Syscall raising an exception softwarely, i'm doubtful about this demand.

Zettablade : if not, "move $a5, 0 (options)" must be before syscall. By the way, your name tells me something... DCEMU forums ?
Ha! Nah, I hate DCEmu. They banned me for insulting their lua scripters :P
I usually hang out on the psp-programming irc. Thought I do idle in math's psp chan and the noobzOT chan.
Last edited by Zettablade on Thu Nov 23, 2006 1:37 am, edited 1 time in total.
Zettablade
Posts: 71
Joined: Fri May 05, 2006 5:59 pm

Post by Zettablade »

It looks like adding nop after that jump fixed it. thx :)
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

hlide wrote:
adrahil wrote: would give something like this:

Code: Select all

.............
_start:
# Create Thread
   move $a0, _thread_name (the label of the thread name
   move $a1, _main_thread_func (the label of the function)
   move $a2, 20 (priority)
   move $a3, 4000 (stack)
   move $a4, 0 (attribute)
   syscall _sceKernelCreateThread
   move $a5, 0 (options)

.............
Adrahil : are you sure "syscall" demands a delay slot instruction as branchs and jumps do ? I never heard about. Syscall raising an exception softwarely, i'm doubtful about this demand.

Zettablade : if not, "move $a5, 0 (options)" must be before syscall. By the way, your name tells me something... DCEMU forums ?
Yeah, sorry :P I never use them, so i forgot that part :)
Zettablade
Posts: 71
Joined: Fri May 05, 2006 5:59 pm

Post by Zettablade »

btw, what does .set do? Google isn't telling me anything....
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Set flags for the assembler. Like "noreorder" will tell it to not reorder the ops to try optimizing.
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
User avatar
Saotome
Posts: 182
Joined: Sat Apr 03, 2004 3:45 am

Post by Saotome »

Zettablade wrote:Ha! Nah, I hate DCEmu. They banned me for insulting their lua scripters :P
I usually hang out on the psp-programming irc. Thought I do idle in math's psp chan and the noobzOT chan.
I like your style :) (a little offtopic but I hope there will never be a lua player version for PS3... you hear me shine?! ;P)

btw adrahil, there are no a4 and a5 registers. IIRC v0 and v1 are used instead.
infj
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

Saotome wrote:
Zettablade wrote:Ha! Nah, I hate DCEmu. They banned me for insulting their lua scripters :P
I usually hang out on the psp-programming irc. Thought I do idle in math's psp chan and the noobzOT chan.
I like your style :) (a little offtopic but I hope there will never be a lua player version for PS3... you hear me shine?! ;P)

btw adrahil, there are no a4 and a5 registers. IIRC v0 and v1 are used instead.
they do exist but are named t0 and t1 in old naming.

In fact, when you compile with gcc, it uses t0-t3 as a4-a7 for arguments of c functions.

so I suspect gcc and sony use n32 namings by default and not o32 namings (t0-t3 are not the same registers in n32 and o32 namings, in n32 t0-t3 are t4-t7 in o32 indeed), because when I try to disassemble with psp-objdump without n32 option, it disassembles my C functions with more than 4 arguments in o32 naming by default : they uses t0-t3 which are indeed a4-a7 in n32 naming.
Last edited by hlide on Thu Nov 23, 2006 5:25 am, edited 1 time in total.
Zettablade
Posts: 71
Joined: Fri May 05, 2006 5:59 pm

Post by Zettablade »

Raphael wrote:Set flags for the assembler. Like "noreorder" will tell it to not reorder the ops to try optimizing.
Is there a list of the flags anywhere?
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

Zettablade wrote:
Raphael wrote:Set flags for the assembler. Like "noreorder" will tell it to not reorder the ops to try optimizing.
Is there a list of the flags anywhere?
.set push --> save all settings
.set reorder/noreorder --> let/don't let assembler reorder instructions
.set at/noat --> let/don't let assembler use the register $at in instruction aliases (li,la, etc.)
.set pop --> restore saved settings

they are the only ones i know so far
User avatar
Saotome
Posts: 182
Joined: Sat Apr 03, 2004 3:45 am

Post by Saotome »

hlide wrote:...n32 and o32 stuff...
Ah ok, didn't know that there are different naming conventions. I only know this list from the PS2Basics.pdf and thought thats standard for all MIPS CPUs

Code: Select all

#define zero $0 // Always 0
#define at $1 // Assembler temporary
#define v0 $2 // Function return
#define v1 $3 //
#define a0 $4 // Function arguments
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 // Temporaries. No need
#define t1 $9 // to preserve in your
#define t2 $10 // functions.
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 // Saved Temporaries.
#define s1 $17 // Make sure to restore
#define s2 $18 // to original value
#define s3 $19 // if your function
#define s4 $20 // changes their value.
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 // More Temporaries.
#define t9 $25
#define k0 $26 // Reserved for Kernel
#define k1 $27
#define gp $28 // Global Pointer
#define sp $29 // Stack Pointer
#define fp $30 // Frame Pointer
#define ra $31 // Function Return Address
infj
Post Reply