section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ecx,10
mov eax, '1'
l1:
mov [num], eax
mov eax, 4
mov ebx, 1
push ecx <----
mov ecx, num <---
mov edx, 1
int 0x80
mov eax, [num] <---
sub eax, '0'
inc eax
add eax, '0'
pop ecx <----
loop l1
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .bss
num resb 1
Asked
Active
Viewed 66 times
0

Peter Cordes
- 328,167
- 45
- 605
- 847

Joseph
- 1
-
Do you understand what `int 0x80` does? – tkausl Mar 12 '23 at 15:01
-
It is common in assembly to repurpose CPU registers. Here `ecx` is being used as loop counter by the `loop` instruction, and has been set up to count down from 10, but during the body of the loop, `ecx` is needed for another purpose (the system call, via `int 0x80`), hence the `push` & `pop`. – Erik Eidt Mar 12 '23 at 15:04
-
@ErikEidt so we saved the value of ecx in the stack ? Because we needed it for another purpose? And that purpose to mov num into ecx? – Joseph Mar 12 '23 at 15:10
-
@tkausl no im a beginner would you explain thanks. – Joseph Mar 12 '23 at 15:12
-
2Yes, that's right. Study the system call to see what it does. In short, you put values in registers and then do `int 0x80` and the operating system knows what you want it to do by looking at the values in the registers. In other words, the operating system is taking parameters in registers, and those parameters tell it what to do for the system call. – Erik Eidt Mar 12 '23 at 15:15
-
@ErikEidt thanks Erik i appreciate your time. – Joseph Mar 12 '23 at 15:40
-
1Instead of picking a different register (like ESI) as the loop counter, this inefficient code picked ECX which it also needs to use as a system-call arg inside the loop body. So it has to save/restore. It also has an actual bug, doing 4-byte loads/stores to `num` where it only reserved 1 byte (`resb 1`). It's also pretty inefficient and over-complicated; it could have just doing `mov byte [num], '1'` ahead of the loop, and `inc byte [num]` inside the loop. Subtracting/adding `'0'` cancels out to just incrementing the ASCII digit character. – Peter Cordes Mar 12 '23 at 18:15
-
(Of course, using a different register as a loop counter means you can't use the `loop` instruction, but you normally don't want to anyway [because it's slow on many CPUs](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently).) – Peter Cordes Mar 12 '23 at 18:33
-
@PeterCordes amazing... thanks for commenting.. so if we used ESI as the counter we wouldn't pushed ECX and pop it again?.. but why if we used another register we can't use loop instruction is it because loop instruction attached to ECX?... and if you can give me some good sources to study assembly. – Joseph Mar 12 '23 at 21:36
-
1The instruction-set manual would be a good place to start for understanding each instruction separately. Notice that `loop` doesn't mention ECX explicitly; it uses it implicitly. https://www.felixcloutier.com/x86/loop:loopcc and see also [How exactly does the x86 LOOP instruction work?](https://stackoverflow.com/a/46881622). But if you didn't already know that, a tutorial would be a good place to start. There are some in https://stackoverflow.com/tags/x86/info – Peter Cordes Mar 12 '23 at 21:47