0

i want to print dynamic array with printf... But after call printf i have some strange behavior(for me). Call printf changes unrelated register.

My questions:

  1. In print_array gdb show that after printf register %rcx was changed... Why is this happening and and how to fix it?
  2. If we comment out print_array the program crashes in call free... I really don't understand why? Help please

All program:

    .text
    .global main

    print_array:
    pushq   %rbp
    movq    %rsp, %rbp
    
    xor %rax, %rax
    mov %rdi, %rbx
    mov %rsi, %rax
    dec %rax
    imul $4, %rax
    add %rax, %rdi
    mov %rdi, %rcx

    print_loop:
    cmp %rbx, %rcx
    jl stop

    xor %rdi, %rdi
    xor %rsi, %rsi
    lea one_element(%rip), %rdi
    mov (%rbx), %rsi
    xor %rax, %rax
    call printf

    add $4, %rbx
    jmp print_loop
    stop:
    popq    %rbp
    retq

    main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $24, %edi
    callq   malloc
    movq    %rax, -8(%rbp)
    cmpq    $0, -8(%rbp)
    je broken
    movl    $1, (%rax)
    movl    $2, 4(%rax)
    movl    $3, 8(%rax)
    movl    $4, 12(%rax)
    movl    $5, 16(%rax)
    movl    $6, 20(%rax)
    mov %rax, %r10

    mov %rax, %rdi
    mov $6, %rsi
    call print_array

    xor %rdi, %rdi
    xor %rsi, %rsi
    xor %rcx, %rcx
    lea elements(%rip), %rdi
    mov (%r10), %rsi
    mov 4(%r10), %rdx
    mov 8(%r10), %rcx
    mov 12(%r10), %r8
    mov 16(%r10), %r9
    xor %rax, %rax
    call printf

    mov %r10, %rdi
    callq free
    xor %rax, %rax
    popq    %rbp
    retq
    broken:
        xor %rax, %rax
        popq    %rbp
        retq

    data:
    elements: .string "First element: %d second: %d third: %d fourth: %d fifth: %d\n"
    one_element: .string "Element: %d\n"
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
xperious
  • 239
  • 3
  • 10
  • @Peter Cordes, help if you can – xperious Dec 29 '21 at 06:42
  • I meant to link [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) as the first duplicate. That's fixed now, look at the top of the page. – Peter Cordes Dec 29 '21 at 06:44
  • @PeterCordes %rcx - for fourth argument, but i call printf in loop with just 2 arguments – xperious Dec 29 '21 at 06:45
  • 1
    rcx is clobbered whether it's used for an argument or not. Same for all the other argument-passing registers; they are all call-clobbered. – Nate Eldredge Dec 29 '21 at 06:48
  • @NateEldredge hmm... rdi, rsi, rcx, rbx, r11 really clobbered after ALL call instruction? – xperious Dec 29 '21 at 06:59
  • 1
    Not RBX, it's call-preserved (aka non-volatile) in this calling convention. See [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) - that's why I linked it. Of course some functions might not actually modify every register they're allowed to, but without knowing their internal implementation you have to *assume* that they do. e.g. very few functions will touch `mm7` or `st(7)`, legacy MMX / x87 registers. I linked [What registers are preserved through a linux x86-64 function call](https://stackoverflow.com/q/18024672) to explain that c – Peter Cordes Dec 29 '21 at 07:15
  • @PeterCordes thanks, I really didn't know that all these registers would be cleared even if they are not used for pass arguments – xperious Dec 29 '21 at 07:17

0 Answers0