patternMinor
AT&T Assembly - Basic loop & write
Viewed 0 times
writeassemblyloopbasic
Problem
The code loops to display "Hello, World!" ten times. I would like someone to criticize it. I know that's far from being good assembly but I only started learning it a few days ago and I would like to improve.
Would it be better to use the
Also, if someone could explain
Would it be better to use the
%rax registers and syscall instead of int $0x80 ?.section .data
hello: .string "Hello, world!\n"
len = . -hello
.section .bss
.macro write str, len
movl $WRITE, %eax
movl $STDOUT, %ebx
movl \str, %ecx
movl \len, %edx
int $0x80
.endm
.macro exit code
movl $EXIT, %eax
movl \code, %ebx
int $0x80
.endm
.section .text
.globl _start
.equ EXIT, 1
.equ WRITE, 4
.equ STDOUT, 1
_start:
mov $1, %esi
l:
write $hello, $len
inc %esi
cmp $10, %esi
jle l
exit $0Also, if someone could explain
len = . -hello, that's the only thing I couldn't understand and copied online.Solution
Let's start with the easy one:
Just one of those tricks you learn. While you could manually put the length into
As for the code itself, let me start with the main point: Comments.
Assembly can be tricky to code correctly, and sometimes is even harder to maintain. Especially when you can't figure out what #@%! the guy who was writing it was trying to do.
I realize that this is just a beginner's project. But you should acquire the habit of commenting early:
As an example:
exit $0 ; Exit the application with return code 0
While to a veteran assembly programmer this comment may seem obvious, to a beginner (and everyone is a beginner at some point), it makes the intent significantly clearer. Just a few words of text can take a screen full of numbers and symbols and provide clarity. Maintainers of your code (as well as your future self) will thank you.
Next (in no particular order) I would look at this section of code:
As I'm sure you are aware, the purpose of the
Nothing magical, but it does save an instruction.
Next we've got
Wouldn't it be better to use the %rax registers and syscall instead of int $0x80?
It absolutely would be better to use
Note: The function number (and where each of the arguments go) are different between
. - hello - You need to understand that hello refers to an address. And that . refers to the "current" address. So . - hello is the distance between the current location and hello; effectively the length of hello.Just one of those tricks you learn. While you could manually put the length into
len, there's always the chance that someday someone would change the contents of hello, and forget to change len. Done this way, it's self-maintaining. Being able to compute this at 'assembly time' rather than counting bytes during run time is also a bonus.As for the code itself, let me start with the main point: Comments.
Assembly can be tricky to code correctly, and sometimes is even harder to maintain. Especially when you can't figure out what #@%! the guy who was writing it was trying to do.
I realize that this is just a beginner's project. But you should acquire the habit of commenting early:
- Comments at the top of the code telling the purpose of the file.
- Comments at the top of routines (and macros) telling what they do.
- Comments at the end of individual statements describing the intent.
As an example:
exit $0 ; Exit the application with return code 0
While to a veteran assembly programmer this comment may seem obvious, to a beginner (and everyone is a beginner at some point), it makes the intent significantly clearer. Just a few words of text can take a screen full of numbers and symbols and provide clarity. Maintainers of your code (as well as your future self) will thank you.
Next (in no particular order) I would look at this section of code:
mov $1, %esi
l:
write $hello, $len
inc %esi
cmp $10, %esi
jle lAs I'm sure you are aware, the purpose of the
cmp instruction is to set the flags so that you can use conditional instructions like jle. However, there are other instructions that adjust those same flags. For example, dec:mov $10, %esi
l:
write $hello, $len
dec %esi
jnz lNothing magical, but it does save an instruction.
Next we've got
Wouldn't it be better to use the %rax registers and syscall instead of int $0x80?
It absolutely would be better to use
syscall. IF you were programming for 64bit. int 0x80 is correct for 32bit. And when I say 32/64bit, I'm referring to whether the application is 32 bit or 64bit, not the OS you are running on.Note: The function number (and where each of the arguments go) are different between
int 0x80 and syscall.Code Snippets
mov $1, %esi
l:
write $hello, $len
inc %esi
cmp $10, %esi
jle lmov $10, %esi
l:
write $hello, $len
dec %esi
jnz lContext
StackExchange Code Review Q#150822, answer score: 6
Revisions (0)
No revisions yet.