I can now call asm from a C shell.
Rather than do this, are there any documented... system calls? I.e. can I get I/O via some form of
call to write to the console/read from it?
Any pointers to hardware access too from asm The IO strip or the leds?
Has anyone documented this please?
Any pointers please?
TIA Dave
Re: asm printf?
There was a "linux assembly programming" series of tutorials in LinuxFormat recently. IIRC the file you might be looking for is http://lxr.free-electrons.com/source/in ... =3.1;a=arm
or http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
And google seems to pick out a few linux assembly tutorials too
Regarding "the IO strip" see http://elinux.org/Rpi_Low-level_peripherals and http://www.raspberrypi.org/wp-content/u ... herals.pdf
Best of luck
or http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
And google seems to pick out a few linux assembly tutorials too

Regarding "the IO strip" see http://elinux.org/Rpi_Low-level_peripherals and http://www.raspberrypi.org/wp-content/u ... herals.pdf
Best of luck

Re: asm printf?
Are they generic, or specific to Debian... or rpi?
http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
2005 seems rather old for rpi?
Thanks for the GPIO references. Looks like that is complete. I'll chase it up
for sw i/f.
Dave
http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
2005 seems rather old for rpi?
Thanks for the GPIO references. Looks like that is complete. I'll chase it up
for sw i/f.
Dave
Re: asm printf?
A library is a library; you can call all the C library from assembler just like you can from C. You need to kow the C calling convention, which says what to put on the stack and what to put in registers and what to do after the call to get the result and tidy up, but all that is simple enough.
So the printf for assembler... is printf.
And it was a pain to find, but the EABI calling conventions for Debian Armel is documented here.
So the printf for assembler... is printf.
And it was a pain to find, but the EABI calling conventions for Debian Armel is documented here.
Re: asm printf?
http://omappedia.org/wiki/Writing_ARM_Assembly
Thanks for that.
Clarifies the interface, c-asm.
Should I take it then that there is no svc call for console I/O?
I want to remain in asm and drop the C shell.
Dave
Thanks for that.
Clarifies the interface, c-asm.
Should I take it then that there is no svc call for console I/O?
I want to remain in asm and drop the C shell.
Dave
Re: asm printf?
In this free book "Programming From The Ground Up" you can find sample codes for x86 linux asm.
In short, everything you write to /dev/stdout will appear on the screen. From asm you open it as a file and write to it.
In short, everything you write to /dev/stdout will appear on the screen. From asm you open it as a file and write to it.
Re: asm printf?
The link I provided is only "specific" to the 3.1.x release of the Linux kernel.dpawson wrote:Are they generic, or specific to Debian... or rpi?
That's because it's such a low-level stable interface, it doesn't change much (which is a good thing). Everything else layers up on top of this...http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
2005 seems rather old for rpi?

Re: asm printf?
Found the LXF Coding Academy Assembly tutorials - http://www.linuxformat.com/archives?issue=154 to issue 157 - but only available to subscribers.
Re: asm printf?
Then you need to know what crt0 does so you can replace it with your code. This thread should give you a few hints as to where to look.dpawson wrote: Should I take it then that there is no svc call for console I/O?
I want to remain in asm and drop the C shell.
The calls to the kernel as opposed to the calls to the C library are those functions documented in section 2 of man as opposed to section 3. However I do not know if this makes a difference to code you write. It might be possible to use a software interupt or whatever ARM has, but you'd need to dive further into Armel and Linux source to find out. Maybe if you find the source to the C libraries that wrap those functions...
You are now going where very few people bother going. For most programmers, C with a few functions in assembler is all they ever need. So the source code for crt0 and those libraries is likely to be more useful than any other resource. In particular I can point the way, but I've not been there for decades and never in Linux or ARM.
Re: asm printf?
I'd agree with rurwin - "pure assembly" is really only useful if you're building truly tiny systems - look at http://asm.sourceforge.net/asmutils.html and http://www.fefe.de/dietlibc/ for examples (and possibly more useful links). But with the abundant resources of the RPi, it doesn't really seem necessary - just stick with C. Unless you're doing it purely as a learning exercise of course 

-
- Posts: 406
- Joined: Sun Nov 20, 2011 11:37 am
- Contact: Website
Re: asm printf?
Sorry - I know I've posted this somewhere else, but it is relevant here, I think.
I don't fully understand this, but it looks like the string is loaded into r1, the string's length goes in r2. Then we make r7 hold the value 4. This must the code to print to the screen, I think.
(To end a program, you make this register hold 1, as you can see later ... ).
Then "swi $0" is the message to the kernel to do something.
I'm keen to learn some more assembly code (just out of interest rather than for any practical project).


Re: asm printf?
Yeah, this ties up with the link I posted earlier http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
4 is __NR_write and 1 is __NR_exit
But that's about as far as my knowledge goes, you're really best off buying/borrowing a book or something
4 is __NR_write and 1 is __NR_exit
But that's about as far as my knowledge goes, you're really best off buying/borrowing a book or something

Re: asm printf?
antiloquax wrote:
Sorry - I know I've posted this somewhere else, but it is relevant here, I think.
I don't fully understand this, but it looks like the string is loaded into r1, the string's length goes in r2. Then we make r7 hold the value 4. This must the code to print to the screen, I think.
(To end a program, you make this register hold 1, as you can see later ... ).
Then "swi $0" is the message to the kernel to do something.
OK, that makes sense. The C declaration of write(2) is:AndrewS wrote:Yeah, this ties up with the link I posted earlier http://lxr.free-electrons.com/source/ar ... =3.1;a=arm
4 is __NR_write and 1 is __NR_exit
Code: Select all
ssize_t write(int fd, const void *buf, size_t count);
r1 is a pointer to the string
r2 is the size of the string
r7 is the system call to use.
Re: asm printf?
10 internet points for rurwin :)
syscalls are done by shoving the parameters into the first 6 registers (it gets a tad more tricky if you have more than 6 arguments), the syscall number into r7, and executing 'swi 0'. This triggers a "software interrupt" (hence 'swi', although the opcode has now been renamed to 'svc' or "supervisor call") which causes execution to jump to the SVC vector in the ARM vector table (and, in the process, puts the processor into a privileged execution state), which dispatches your call off to the relevant handler. about the only tricky thing is if you have 64-bit arguments, as they have to be aligned starting in even-numbered registers. Not sure if any of the Linux syscalls need that, though.
Chapter and verse on argument passing can be had from the Procedure Call Standard for the ARM Architecture
Simon
syscalls are done by shoving the parameters into the first 6 registers (it gets a tad more tricky if you have more than 6 arguments), the syscall number into r7, and executing 'swi 0'. This triggers a "software interrupt" (hence 'swi', although the opcode has now been renamed to 'svc' or "supervisor call") which causes execution to jump to the SVC vector in the ARM vector table (and, in the process, puts the processor into a privileged execution state), which dispatches your call off to the relevant handler. about the only tricky thing is if you have 64-bit arguments, as they have to be aligned starting in even-numbered registers. Not sure if any of the Linux syscalls need that, though.
Chapter and verse on argument passing can be had from the Procedure Call Standard for the ARM Architecture
Simon
Re: asm printf?
Exactly why I'm doing it, purely as a learning exercise.... then documenting it for others.AndrewS wrote:I'd agree with rurwin - "pure assembly" is really only useful if you're building truly tiny systems - look at http://asm.sourceforge.net/asmutils.html and http://www.fefe.de/dietlibc/ for examples (and possibly more useful links). But with the abundant resources of the RPi, it doesn't really seem necessary - just stick with C. Unless you're doing it purely as a learning exercise of course
Agreed it isn't necessary, but then again, how many are doing anything 'necessary' with rpi?
Tks for the pointers all.
Re: asm printf?
As per the imageantiloquax wrote:
I don't fully understand this, but it looks like the string is loaded into r1, the string's length goes in r2. Then we make r7 hold the value 4. This must the code to print to the screen, I think.
(To end a program, you make this register hold 1, as you can see later ... ).
Then "swi $0" is the message to the kernel to do something.
I'm keen to learn some more assembly code (just out of interest rather than for any practical project).
![]()
(I can't get the midori browser to work with the forum or I'd paste it)
.data
msg:
.ascii "Hello World\n"
len = . - msg
.text
.globl _wrmsg
_wrmsg:
mov r0, $1
ldr r1, =msg
ldr r2, =len
mov r7, $4
svc $0
mov r0, $0
mov r7, $1
svc $0
# bx lr appending this fails to return to the calling C code
I think that is the code given in the image.
OK, it works. Produces output.
Why two SVC calls please?
One to svc ??? 4
then one to svc ??? 1
I can call this from C...
With bx lr appended to the end of the asm fails to return though?
Thanks. DaveP
Re: asm printf?
Duh.
RTFM
The comments above imply the second svc is to end the program.
I.e. can delete all after the call to svc #0
(I have changed all the literals from $x to #x in line with ARM conventions)
I guess if I could sort out a register setup this would allow
a start without a call from C. later.
ld parameters?
Now works and returns from asm to the C code.
Thanks to all for the help.
Dave
RTFM
The comments above imply the second svc is to end the program.
I.e. can delete all after the call to svc #0
(I have changed all the literals from $x to #x in line with ARM conventions)
I guess if I could sort out a register setup this would allow
a start without a call from C. later.
ld parameters?
Now works and returns from asm to the C code.
Thanks to all for the help.
Dave
Re: asm printf?
It seems to me that the code in the image is to be executed on its own without a C wrapper, because it starts with a _start label. IIRC, crt0 starts with _start and then calls _main. So I'd guess the code in the image is a direct example of what you need to do.
Re: asm printf?
rurwin wrote:It seems to me that the code in the image is to be executed on its own without a C wrapper, because it starts with a _start label. IIRC, crt0 starts with _start and then calls _main. So I'd guess the code in the image is a direct example of what you need to do.
Yep... or nearly.
Quite standalone
(Has anyone got a browser working with this forum under Debian /rpi?)
.data
msg:
.ascii "Hello World\n"
len = . - msg
.align 8
.text @ wozzat for?
.global main
main: @keep gcc happy
mov r0, #1
ldr r1, =msg
ldr r2, =len
mov r7, #4
svc #0 @service call to 4, print
mov r0, #0
mov r7, #1
svc #0 @service call to 'return' to the OS
.end
That works. HTH Others.
Who needs cissy C @-)
-
- Posts: 406
- Joined: Sun Nov 20, 2011 11:37 am
- Contact: Website
Re: asm printf?
Hi,
Sorry, I missed some of the replies on here - forgot to "watch".
I have been trying to work out how to print a number to the screen. So far, no luck. I've been reading some of the material on syscalls, but I can't get it to work
In the mean-time, I've been playing around with more extremely simple code. Here's a little program that doubles the number 7!

Sorry, I missed some of the replies on here - forgot to "watch".
I have been trying to work out how to print a number to the screen. So far, no luck. I've been reading some of the material on syscalls, but I can't get it to work

In the mean-time, I've been playing around with more extremely simple code. Here's a little program that doubles the number 7!
Re: asm printf?
That's the problem with assembler; you need to do all the work yourself, unless you link in the C libraries and call them.antiloquax wrote:I have been trying to work out how to print a number to the screen. So far, no luck. I've been reading some of the material on syscalls, but I can't get it to work
The way we used to do it on the PDP-11 was to have a table of powers of ten. Start at the high end and start subtracting the highest power of ten from your number until it goes negative then take the number of times you subtracted (minus one) plus the value of ASCII '0' (48) and print that as a character. Then do the same for the next power of ten and so on down. Handling leading zero suppression and negative numbers is left as an exercise for the interested reader.

Re: asm printf?
The tutorial code for the LXF articles I linked to earlier is publicly available. The source-code download from LXF156 ( http://www.linuxformat.com/includes/dow ... 6.code.tgz ) contains a library.asm file which contains (amongst others) a lib_print_number function. It's written in x86, so it'll need some conversion to ARM, but the techniques might give you a head start?antiloquax wrote:I have been trying to work out how to print a number to the screen. So far, no luck. I've been reading some of the material on syscalls, but I can't get it to work

-
- Posts: 406
- Joined: Sun Nov 20, 2011 11:37 am
- Contact: Website
Re: asm printf?
Thanks Andrew and rurwin. I've downloaded the library.asm file.
In the mean time, I've been playing with a simple loop program (which uses the C "printf" function: cheating
)
I found that I had to use a different register from r1 for my counter. I'm not really sure why, but it didn't work when I tried using r1. Anyway, that is why I am using r5 to count down and then moving the count into r1 before printing.
Someone will probably explain it better, but I use "subs" to decrement my counter and set the condition code. That way, I don't need to do "cmp", because "bne" will branch if our counter is not zero. I tried using "bpl" (branch if positive or zero), and that worked nicely too.
mark
By the way, rurwin, where did you use a PDP-11? I'm reading Stephen Levy's "Hackers" at the moment and was very interested by the material about the PDP-1 at MIT.
In the mean time, I've been playing with a simple loop program (which uses the C "printf" function: cheating

Code: Select all
.section .data
string:
.asciz "Looping: %d\n"
.text
.globl main
main:
mov r5, $10
.loop:
mov r1, r5
ldr r0, =string
bl printf
subs r5, r5, $1
bne .loop
mov r7, $1
swi $0
Someone will probably explain it better, but I use "subs" to decrement my counter and set the condition code. That way, I don't need to do "cmp", because "bne" will branch if our counter is not zero. I tried using "bpl" (branch if positive or zero), and that worked nicely too.
mark
By the way, rurwin, where did you use a PDP-11? I'm reading Stephen Levy's "Hackers" at the moment and was very interested by the material about the PDP-1 at MIT.
Re: asm printf?
http://www.tofla.iconbar.com/tofla/arm/arm02/index.htmantiloquax wrote:Hi,
Sorry, I missed some of the replies on here - forgot to "watch".
I have been trying to work out how to print a number to the screen. So far, no luck. I've been reading some of the material on syscalls, but I can't get it to work
In the mean-time, I've been playing around with more extremely simple code. Here's a little program that doubles the number 7!
Looks good, as an exercise too.
Gives integer division.
HTH
-
- Posts: 406
- Joined: Sun Nov 20, 2011 11:37 am
- Contact: Website
Re: asm printf?
That looks interesting. I'll have a read.
I started to think about converting integers into ascii strings and then remembered that the RPi's arm doesn't have built in division!
I used a similar idea to the one rurwin mentioned in a little Python program I wrote to do UK National Curriculum grid multiplication. I wanted to get the values of the hundreds, tens and units etc "columns". Here's the function I wrote ("split").

I started to think about converting integers into ascii strings and then remembered that the RPi's arm doesn't have built in division!
I used a similar idea to the one rurwin mentioned in a little Python program I wrote to do UK National Curriculum grid multiplication. I wanted to get the values of the hundreds, tens and units etc "columns". Here's the function I wrote ("split").
