Skip to: Site menu | Main content


Welcome to PSP-Programming.com, a place for developers to get together.

Welcome to the forums. Here you can find other user tutorials as well as homebrew releases and the source code repository. You can also ask for help with your code here and post your own homebrew!

PSP-Programming.com Forums
March 13, 2010, 05:47:38 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

News: Join our IRC channel: ##psp-programming on freenode
Home Help Search Shop Login Register
Digg This!
Pages: [1]
Print
Author Topic: [Tutorial] How to inline ASM in C (gcc)  (Read 6745 times)
harleyg
Give miinaturvat Points!
Hero Member
*****

Karma: +11/-14
Offline Offline

Posts: 715
462.95 points

View Inventory
Send Money to harleyg


View Profile
« on: August 18, 2006, 04:20:19 PM »

How to inline ASM in C (gcc)

In your code you will use the asm(); function, which you can use to inline asm in C. If you don't understand what inline means, it's basically using ASM in C.

First, set headers, module info and start main.
Code:
#include <pspkernel.h>
#include <pspdebug.h>

PSP_MODULE_INFO("Hello World in ASM", 0, 1, 1);

int main(void) {


When inlining ASM in C, you can set a variable in C, in out case we will call it msg, and use it in the ASM code.
Code:
char *msg = "Hello world\n";



Setup the psp screen.
Code:
pspDebugScreenInit();



Now, using the asm() function you can make the psp print this code...
Code:
asm("lui $4, %%hi(%0)\n"
"jal pspDebugScreenPrintf\n"
"addiu $4,$4,%%lo(%0)\n"
"nop\n"
: : "g" (msg));


lui, load upper immediate.
$4, $4 will be loaded later.
%%hi, this will grab the upper 16bits of (val).
$0, this is this first argument passed into the function.

jal, jump and load.
pspDebugScreenPrintf, the jal loads pspDebugScreenPrintf and that prints $4.

addiu, add immmediate unsigned.
$4,$4,%%lo(%0), $4 + %%lo(%0) (lower 16 bits of the first arguement passed into the function) = $4.

nop, no operation. This means that instead of setting $4 after jal, you can set before. This is used for aligning code.

: : "g" (msg));, loads the variable msg ($0) and ends the asm function. This requires -02 on gcc, if that isnt by default.


Return 0 and close main.
Code:
return 0;
}




Your code shoud look like this.
Code:
#include <pspkernel.h>
#include <pspdebug.h>

PSP_MODULE_INFO("Hello World", 0, 1, 1);

int main(void) {
char *msg = "Hello world!\n";
pspDebugScreenInit();
asm("lui $4, %%hi(%0)\n"
"jal pspDebugScreenPrintf\n"
"addiu $4,$4,%%lo(%0)\n"
"nop\n"
: : "g" (msg));
return 0;
}


Your Makefile.
Code:
TARGET = hello
OBJS = main.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World in ASM

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak



Ta-da, it should say hello world!



Yes, this way probably does suck, but im still learning MIPS ASM myself Smile
Big thanks to pspdev and siberian for helping me Razz
Logged


nathan42100
Give miinaturvat Points!
Administrator
Hero Member
*

Karma: +31/-2
Offline Offline

Posts: 1158
804.49 points

View Inventory
Send Money to nathan42100


View Profile WWW
« Reply #1 on: August 18, 2006, 07:26:48 PM »

nice!
Logged

All of my work is released under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
dn ʎɐʍ sıɥʇ
Help support my computer projects!

boom
Jr. Member
**

Karma: +2/-2
Offline Offline

Posts: 83
162.04 points

View Inventory
Send Money to boom


View Profile WWW
« Reply #2 on: August 19, 2006, 02:27:48 AM »

cool, it does look REALLY CONFUSING Exclamation
do you use the same method of making a C/C++ eboot just with the asm code cuz the thing that lets you make C codes wont work on my computer
  Very Happy  Smile  Sad  Mad  Crying or Very sad

WHHHYYYYYYYYYYYYYYYYYYYYYYYYYY!!!!!!!!!!!!!!!!
Logged

Zettablade
C/C++ Developer
Full Member
*

Karma: +5/-8
Offline Offline

Posts: 108
2041.97 points

View Inventory
Send Money to Zettablade

Mudkip > You


View Profile
« Reply #3 on: August 19, 2006, 02:41:30 AM »

Of course, it's inlined. Just type 'make', nothing has changed.

Anyways, awsome tut. And good luck with your mips asm.  Wink
Logged

SG57
Sr. Member
****

Karma: +7/-37
Offline Offline

Posts: 474
1140.80 points

View Inventory
Send Money to SG57


View Profile
« Reply #4 on: August 19, 2006, 04:14:28 PM »

Here's another good reference taken from an answer to my question at ps2dev...

A good comparison from a C routine of an addition test between variables, to an assembly routine of an addition test between variables.

I use this as a sample to learn from...  Like how to use a loop for example.   I make little guesses of how they work, then check it with a quick search of the internet.  Keeps me going and interested to see if Im right Very Happy
Code:

void AddTest()
{


int num1=5;
int num2=10;
int out=0;
int to = 5;
float r17,r16;
r16=0;
r17=0;
for(int i=0;i<to;i++)
{
   float res = num1*num2;
   r16 = res;
   r17 = r16+r17;
}
printf("C Res:%f",r17);

num1 =5;
num2 = 10;
out = 0;
to = 5;

asm __volatile__ ("\n\
ori $5,$0,0\n\
ori $17,$0,0\n\
loop:\n\
mul %1,%2\n\
mflo $16\n\
addu $19,$16,$17\n\
move $17,$19\n\
addiu $5,$5,1\n\
bne $5,%3,loop\n\
nop\n\
move %0,$17\n\
":"=r"(out):"r"(num1),"r"(num2),"r"(to)
);

printf("Asm Result:%d \n",out);
}

harleyg uses the " to start and stop a line, while you can easily use the backwards slash (\) to show 'next line' without a need for the multiple ".  I find it a tad easier to read with the \'s since my editor doesnt highlight hte entire text behind it, where as the " and ", everything in between is highlighted, making it look like a string for printing Sad  But that's just me, as I too am learning ASM step by step, so thought Id share with you if thats ok Embarassed
Logged
harleyg
Give miinaturvat Points!
Hero Member
*****

Karma: +11/-14
Offline Offline

Posts: 715
462.95 points

View Inventory
Send Money to harleyg


View Profile
« Reply #5 on: August 19, 2006, 04:17:14 PM »

Sure, i was only showed that form what SiberianSTAR said.
Logged
PaulC
Newbie
*

Karma: +2/-1
Offline Offline

Posts: 49
1661.44 points

View Inventory
Send Money to PaulC

View Profile
« Reply #6 on: October 18, 2008, 02:58:07 PM »

How to inline ASM in C (gcc)

When I run this, it prints out a garbage value. Anyone know why?
Logged
macthefork
Newbie
*

Karma: +5/-0
Offline Offline

Posts: 22
721.82 points

View Inventory
Send Money to macthefork

View Profile
« Reply #7 on: October 19, 2008, 12:42:51 AM »

The problem is the newer compilers (from when that was probably written) are doing some aggressive inline assembly optimisation (or alternatively dumb Razz). When you compile that you get:

Code:
; ======================================================
; Subroutine main - Address 0x00000280
main:           ; Refs: 0x0000009C
        addiu      $sp, $sp, -0x8                           ; 0x00000280: 0x27BDFFF8 '...''
        sw         $ra, 0x0($sp)                            ; 0x00000284: 0xAFBF0000 '....'
        jal        pspDebugScreenInit                       ; 0x00000288: 0x0C00029D '....'
        nop                                                 ; 0x0000028C: 0x00000000 '....'
        jal        pspDebugScreenPrintf                     ; 0x00000290: 0x0C0002A5 '....'
        lui        $a0, 0x1                                 ; 0x00000294: 0x3C040001 '...<'
        addiu      $a0, $a0, -0xA3C                         ; 0x00000298: 0x2484F5C4 '...$'
        nop                                                 ; 0x0000029C: 0x00000000 '....'
        lw         $ra, 0x0($sp)                            ; 0x000002A0: 0x8FBF0000 '....'
        move       $v0, $zr                                 ; 0x000002A4: 0x00001021 '!...'
        jr         $ra                                      ; 0x000002A8: 0x03E00008 '....'
        addiu      $sp, $sp, 0x8                            ; 0x000002AC: 0x27BD0008 '...''

If you look at the call to pspDebugScreenPrintf the final loading of the pointer is now after the call has finished so the function will try and print what ever is at address 0x10000 (well it will be relocated of course).

Changing the asm to:

Code:
    asm __volatile__ ("la $4, %0\n"
        "jal pspDebugScreenPrintf\n"
        : : "g" (msg));

Will fix it for the time being, you should always double check that the assembly code you wanted it outputted correctly. Even better just don't use inline asm for anything but the cases where you have no choice (like VFPU code) as in reality the compiler can probably do a better job at generating decent asm code Wink
Logged
PaulC
Newbie
*

Karma: +2/-1
Offline Offline

Posts: 49
1661.44 points

View Inventory
Send Money to PaulC

View Profile
« Reply #8 on: October 19, 2008, 03:01:22 AM »

Thanks!

I'm sure the compiler can do a better job and I know better than to start going low-level if I can help it, but I need to start learning this for part of my coursework and it's nice that there's some relevant assembly on here. The "Hello World" example should be a good entry point once I know enough to start adding my own code.
Logged
macthefork
Newbie
*

Karma: +5/-0
Offline Offline

Posts: 22
721.82 points

View Inventory
Send Money to macthefork

View Profile
« Reply #9 on: October 19, 2008, 07:20:26 AM »

If you want to write assembly I would suggest doing it in it's own file, that way the compiler doesn't play around with the ordering of instructions.
Logged
Raiden
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 7
381.65 points

View Inventory
Send Money to Raiden

View Profile
« Reply #10 on: November 11, 2009, 11:53:04 AM »

I know this thread is old, but I have to bump it.
I´ve a real noob question and I hope you aren´t bothered by me Surprised
Is there a chance to compile this without cygwin? I´m currently using pspsdk, which is as far as I know only for C.
Hope you can answer my question!
Logged
mowglisanu

Hero Member
*****

Karma: +27/-10
Offline Offline

Posts: 568
911.87 points

View Inventory
Send Money to mowglisanu


View Profile
« Reply #11 on: November 11, 2009, 02:33:54 PM »

As the title says "[Tutorial] How to inline ASM in C (gcc)"
so it is C at least in gcc.
Logged

Pages: [1]
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.245 seconds with 35 queries.
Sister Sites: Guitar Hero 4   BrokeniTouch.com