Reputation: 1146
I am new at assembly and am trying to wrap my head around function calling in x86. I am provided the following code:
read_integer:
push ebp
mov ebp, esp
sub esp, 8
mov dword [ebp-4], '0'
mov dword [ebp-8], 0
push ebx
push ecx
push edx
.read_loop:
mov eax, 10
mul dword [ebp-8]
add eax, [ebp-4]
sub eax, '0'
mov [ebp-8], eax
mov eax, 3
mov ebx, 0
lea ecx, [ebp-4]
mov edx, 1
int 0x80
cmp dword [ebp-4], 10
jne .read_loop
ret
I can call the read_integer
function using call read_integer
. However when I try to do the same for .read_loop
using call .read_loop
I get the error :
.read_loop is not defined.
What am I doing wrong?
Upvotes: 0
Views: 227
Reputation: 58507
.read_loop
is not meant to be call
ed. It's a label local to read_integer
marking the start of a loop.
If you take a look at the end of read_integer
you see:
cmp dword [ebp-4], 10
jne .read_loop
Which will jump back to .read_loop
as long as [ebp-4]
doesn't equal 10. This is similar to if you had written the following in C:
do {
// Whatever
} while (*(ebp-4) != 10);
To be able to jump somewhere you need to specify where to jump. Hardcoding the location would be really inconvenient, so you use labels and let the assembler figure out which address that label corresponds to.
But you might only want some labels to be visible within a certain scope (e.g. within read_integer
). Perhaps you want to be able to use that same label name in some other function, or perhaps you just want to make it clear to whoever is reading the code that the label is local to the function. So some assemblers provide syntax for making a label local, as described by @Jean-FrançoisFabre.
Some assemblers go one step further and allow "anonymous" labels, such as:
1:
jmp 2f ; f for forwards
; Whatever
jmp 1b ; b for backwards
2:
Or:
-:
jp + ; this is Z80 assembly, so jp isn't a typo
; Whatever
jp -
+:
Upvotes: 1
Reputation: 140287
the dot in .read_loop
means that the label is local.
It is only visible inside the same "scope" made of 2 global labels.
global_label_1:
code
.local_label
code
jne .local_label <=== no ambiguity, the label is locally defined, jumps to the label above
global_label_2:
code
.local_label <=== same name but different scope
code
It's useful because the code can be copied/pasted several times in different procedures without naming conflicts.
In your case, removing the leading dot will solved it: you want it global.
read_loop:
mov eax, 10
...
call read_loop
EDIT: some assemblers also allow to access the inner label like this: call read_integer.read_loop
Upvotes: 1