antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Absolute beginner at Assembly Code!

Sat May 19, 2012 6:58 pm

hellocode.png
hellocode.png (5.6 KiB) Viewed 4724 times
hellooutput.png
hellooutput.png (34.8 KiB) Viewed 4724 times
I have managed to get a simple "Hello World" program to work! :shock:
Hopefully, now I have more of an idea what the assembler program should look like, I will be able to do some more.
mark


User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Re: Absolute beginner at Assembly Code!

Sat May 19, 2012 7:32 pm

Very good! Oh and thank you. I'll probably find this very useful later on.

Here's something in return:

Code: Select all

grep __NR_ /usr/include/asm/unistd.h

User avatar
Dave_G_2
Posts: 196
Joined: Sat Apr 14, 2012 7:04 pm

Re: Absolute beginner at Assembly Code!

Sat May 19, 2012 7:38 pm

@antiloquax

If you don't already have it, get yourself a list of the Linux System calls to use with swi.

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Sat May 19, 2012 10:55 pm

Thanks for your replies! I'm hoping to have a bit more time to play with assembly code tomorrow!

User avatar
RaspberryPie
Posts: 20
Joined: Thu Apr 26, 2012 3:49 pm
Location: florida
Contact: Website

Re: Absolute beginner at Assembly Code!

Tue May 22, 2012 6:48 pm

Keep posting working code, this is a very interesting topic..

cant wait for my pie!
A Raspberry a Day
Keep the Student at Play
So Get Your Slice of Pi
Let your programming Fly

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Mon May 28, 2012 1:41 pm

Okay, this is very basic, but I am learning from doing simple things:
Image

And this shows how I assembled and linked it and got the output.
Image

mark

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 8:49 am

I've got a copy of Knuth's "The Art of Computer Programming". I see I am going to struggle with the level of the mathematics :oops:
Anyway, I was having a look at the first algorithm (Euclid's Greatest Common Divisor).
I came up with this. It's in asm, although I use "printf" to supply some output.
I'm sure this is not the best way to do it! But like I say, I am a beginner. It does seem to work.
Anyway, if you have any suggestions as to how I could improve on this effort, please let me know.
Image

tufty
Posts: 1454
Joined: Sun Sep 11, 2011 2:32 pm

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 9:56 am

A few comments.

First, TAOCP is essential reading and you won't regret it.
Second, you can post your code direct using [ code ] markup.
Third, loopa and loopb are equivalent, and can be replaced by a single label
Fourth, line 30 seems to miss the case where you're <0

Simon

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 11:14 am

Hi Simon,
Thanks for your comments. I can't believe I didn't realise that I didn't need loopa and loopb (like I said, I'm a beginner).
In line 30, it's never going to be less than zero, since r4 is the remainder. I think I could have just put

Code: Select all

mov r3, r1
I've also been reading about using immediate values. It just so happens that the example from TAOCP works, but I think I should have used

Code: Select all

ldr r2, =6099
(for example).

Code: Select all

.section    .data

string:
    .asciz "Euclid's Algorithm: Greatest Common Divisor\n"
result:
    .asciz "Result: %d\n"

.text
    .globl  main

main:
    ldr r0, =string
    bl  printf

    ldr r2, =6099
    ldr r3, =2166

loopa:
loopb:
    sub r4, r2, r3
    cmp r4, r3
    movge   r2, r4
    bge     loopb

    cmp r4, $0
    movgt r2, r3
    movgt r3, r4
    bgt     loopa

    moveq   r1, r3
    ldr r0, =result
    bl printf
    mov r7, $1
    swi 0

tufty
Posts: 1454
Joined: Sun Sep 11, 2011 2:32 pm

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 12:06 pm

antiloquax wrote:In line 30, it's never going to be less than zero, since r4 is the remainder.
insert facepalm.gif here.

Yep, a straight, non-conditional operand is more readable. there are reasons why you might want to use the conditional version, but I won't go into them here.
antiloquax wrote:I've also been reading about using immediate values. It just so happens that the example from TAOCP works, but I think I should have used

Code: Select all

ldr r2, =511
(for example).
It might work, but it's a horrible misuse, and it will bite you in the ass.

The LDRxx mnemonics /all/ load a register from memory or another register. You can't use them to load a literal value (except in the case of the ldr rn, =label construct, which is a shorthand provided by the assembler, not the instruction set itself).

To load a literal value, you need to use MOVxxx, for example

Code: Select all

mov r0, #0xf00d
Where this gets sticky is that the ARM instruction set is strictly 32 bits only, and with a certain number of those bits used for encoding the instruction itself, you aren't going to be able to encode all 32 bits of a literal value. In fact, you can only do 16 bits at a time (12 bits prior to ARMv6T2). This is a major bummer. There are two ways round this:

Code: Select all

.code32
myRoutine: 
...
  ldr r0, _myLiteral  ; load my literal
...
  bx lr
.ltorg
_myLiteral: 
  dc.l 0xfeedface
This is the approach most compilers take - literals are grouped into pools spaced between functions (most commonly directly after the function using them) and then referred to as above. The other approach, which is not compatible with older processors, is

Code: Select all

  mov  r0, #0xface
  movt r0, #0xfeed
It's slightly more succinct in terms of readability, and potentially marginally faster, but doesn't save any space (it's still 64 bits).

You can kinda do something like the latter on older processors, knowing that the immediate values you can load direct are 8 bits in length with a 4 bit rotation. As you can imagine, loading immediate values like this gets a "little" involved, and takes longer and more space than the literal pool approach.
Simon

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 2:24 pm

Thanks again!
I'm afraid you've lost me a bit with the material on loading literals.
I'll have to learn a lot more asm to understand what you are saying.
This is the first program I have ever written in asm (as opposed to copying from websites and making minor changes).
I do plan to adapt the code so it will take input from the user. That will make the problem about immediate values irrelevant, I think.
Mark

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Thu Jun 07, 2012 6:37 pm

Donald Knuth wrote:Many computer users feel that input and output are not actually part of "real" programming; input and output are considered to be tedious tasks that people must perform only because they need to get information in and out of a machine.
Okay, I've had another look at this code and decided to use variables to avoid the mess I was getting into. This goes into my .data section.

Code: Select all

m:
    .long   6099
n:
    .long   2166
These are the values Knuth gives in exercise 4 (page 9). :geek:
Then I've loaded the numbers into my registers like this. I am assuming this is right - first load the address and then a 4-byte chunk into the register. It works, anyway, on my RPi.

Code: Select all

    ldr r5, =m
    ldr r2, [r5], $4

    ldr r5, =n
    ldr r3, [r5], $4
I have also been having a go with some inline use of ASM from C - code. I may post this later.

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Fri Jun 08, 2012 5:40 pm

I am a bit stuck. I've been trying to work out how to print a single character to the screen using ASM (mainly because I am interested in converting numbers to strings and printing them without using "printf").

This page seems to be a good place to look at the syscalls.

My initial aim is to write a simple loop that will count down from 9 to 0 and use the counter to print the number. I've tried adding 48 to the counter (to get to the ascii values for numerals) but I haven't managed to get it to work. I've got the loop working okay and tried to load the correct value into r1, but no numbers came out. I'm not sure if it is something do do with putting a value into r2 (for a string, I've put the length in that register).
Is it to do with data-types? Do I have to tell the processor that I am using byte-values? I tried "ldrb r0" but that didn't work either.
Anyway, if someone knows how to do this, I'd be interested.

User avatar
cheery
Posts: 219
Joined: Wed Jan 25, 2012 9:39 pm

Re: Absolute beginner at Assembly Code!

Fri Jun 08, 2012 6:36 pm

You're looking for __NR_WRITE (4). That's sys_write. "man 2 write" tells you what it needs. (ssize_t write(int fd, const void *buf, size_t count)). You want to write to STDOUT, which has fixed file descriptor number 1.

Code: Select all

digit = pow(10, index)
[--buf] = '0' + (value / digit % 10)

antiloquax
Posts: 406
Joined: Sun Nov 20, 2011 11:37 am
Contact: Website

Re: Absolute beginner at Assembly Code!

Fri Jun 08, 2012 6:53 pm

Thanks Cheery. I'll try that.

Return to “Other languages”

Who is online

Users browsing this forum: No registered users and 6 guests