Page 1 of 1

### Absolute beginner at Assembly Code!

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

### Re: Absolute beginner at Assembly Code!

Posted: Sat May 19, 2012 7:26 pm
Yay you!

### Re: Absolute beginner at Assembly Code!

Posted: 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``

### Re: Absolute beginner at Assembly Code!

Posted: 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.

### Re: Absolute beginner at Assembly Code!

Posted: 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!

### Re: Absolute beginner at Assembly Code!

Posted: Tue May 22, 2012 6:48 pm
Keep posting working code, this is a very interesting topic..

cant wait for my pie!

### Re: Absolute beginner at Assembly Code!

Posted: Mon May 28, 2012 1:41 pm
Okay, this is very basic, but I am learning from doing simple things:

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

mark

### Re: Absolute beginner at Assembly Code!

Posted: 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
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.

### Re: Absolute beginner at Assembly Code!

Posted: Thu Jun 07, 2012 9:56 am

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

### Re: Absolute beginner at Assembly Code!

Posted: 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
``````

### Re: Absolute beginner at Assembly Code!

Posted: 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

### Re: Absolute beginner at Assembly Code!

Posted: 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

### Re: Absolute beginner at Assembly Code!

Posted: 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).
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.

### Re: Absolute beginner at Assembly Code!

Posted: 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.

### Re: Absolute beginner at Assembly Code!

Posted: 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)
``````

### Re: Absolute beginner at Assembly Code!

Posted: Fri Jun 08, 2012 6:53 pm
Thanks Cheery. I'll try that.