0

I'm reading the book "Low level programming" and encouter following code: https://github.com/Apress/low-level-programming/blob/master/listings/chap2/print_call/print_call.asm

section .data

newline_char: db 10
codes: db '0123456789abcdef'

section .text                       
global _start                                                            

print_newline:
    mov rax, 1            ; 'write' syscall identifier
    mov rdi, 1            ; stdout file descriptor
    mov rsi, newline_char ; where do we take data from
    mov rdx, 1            ; the amount of bytes to write
    syscall
   ret

print_hex:
    mov rax, rdi

    mov rdi, 1                  
    mov rdx, 1                  
    mov rcx, 64           ; how far are we shifting rax?      
iterate:                            
    push rax              ; Save the initial rax value
    sub rcx, 4            
    sar rax, cl           ; shift to 60, 56, 52, ... 4, 0
                          ; the cl register is the smallest part of rcx
    and rax, 0xf          ; clear all bits but the lowest four     
    lea rsi, [codes + rax]; take a hexadecimal digit character code
    
    mov rax, 1            ;      

    push rcx              ; syscall will break rcx                
    syscall               ; rax = 1 (31) -- the write identifier,
                          ; rdi = 1 for stdout, 
                          ; rsi = the address of a character, see line 29
    pop rcx                     
    
    pop rax               ; ^ see line 24 ^
    test rcx, rcx         ; rcx = 0 when all digits are shown
    jnz iterate   
    
    ret    

_start:
    mov rdi, 0x1122334455667788
    call print_hex
    call print_newline
    
    mov rax, 60
    xor rdi, rdi
    syscall

From what I understand:

  • The programe will start with _start label first. It's entry point.
  • The _start then call print_hex and print_newline
  • There's no instruction within _start, print_hex and print_newline call/execute the iterate.
  • iterate are defined the same way as print_hex and print_newline. I think its behavior will be the same: only executed when calling upon.
  • But when I run the program, it run the iterate (and print out the result as the author's intension).

It make no sense :)

Can you explain why the iterate is executed?

And another question in nearly similar situation:

https://github.com/Apress/low-level-programming/blob/master/listings/chap2/strlen/strlen.asm

Is that the .loop part of strlen so it will be executed sequentially?

Thang Nguyen
  • 1,161
  • 4
  • 16
  • 30
  • 2
    `print_hex` does not end with a `ret` - so what would you expect to happen? – UnholySheep Sep 11 '21 at 16:51
  • 4
    Variants of this question are often asked, but I don't know which is a good canonical duplicate (maybe [Assembly jumps automatically to next label](https://stackoverflow.com/q/43766549/555045)?). Anyway keep in mind that labels are just names that you give to positions, they don't *do* anything and don't exist at all at the machine code level, `mov rcx, 64` and `push rax` are consecutive instructions. – harold Sep 11 '21 at 16:54
  • Thank you. Coming from high level language (scripting languages), it's unfamiliar to me because the logic is very different. – Thang Nguyen Sep 11 '21 at 17:05
  • 1
    As already stated, labels exist in assembly but they are removed from machine code: ***the processor never sees labels; only instructions change the flow of control.*** Labels affect how the assembler generates machine code for jump and other instructions that reference them. Technically, labels refer to only one point or position in the program, not a whole section of code or data; thus, a label has a specific value, a single memory address. – Erik Eidt Sep 11 '21 at 18:14
  • @harold: [What if there is no return statement in a CALLed block of code in assembly programs](https://stackoverflow.com/q/41205054) is a good canonical, I think. Title fits, and my answer there directly addresses this. You can find it in the [x86 tag wiki](https://stackoverflow.com/tags/x86/info) by searching for "fall through" if you're looking for it again in the future. – Peter Cordes Sep 11 '21 at 22:12
  • 1
    @ThangNguyen: If you're familiar with a language that has `goto` labels, asm labels are exactly like that. They're not functions; execution falls through them. – Peter Cordes Sep 11 '21 at 22:14
  • Or I should say, they're not *necessarily* functions. Functions are a high-level concept you have to implement manually in asm, normally using labels and call/ret instructions. – Peter Cordes Sep 11 '21 at 22:31

0 Answers0