using printf before and inside a loop x86-64 assembly












1















I'm having trouble figuring out how to use printf correctly in this function. So the function is called multInts and is supposed to multiply the first element of the first array with the first element of the second array and continue through the whole array. However, the lab instructions specify that I can't call printf in the main function. So, I need to print out the word "Products:n" and then in each new line after that, print out the product. I don't know how to use printf within the loop, however. The instructor said that we should "call printf in the loop after calculating product" and also to "save and restore caller-save registers before calling printf," but I'm not sure what that means.
Here's what my code looks like so far:



.file   "lab4.s"
.section .rodata

.LC0:
.string "Products: n"
.LC1:
.string "%i n"
.data
sizeIntArrays:
.long 5
sizeShortArrays:
.word 4
intArray1:
.long 10
.long 25
.long 33
.long 48
.long 52
intArray2:
.long 20
.long -37
.long 42
.long -61
.long -10

##### MAIN FUNCTION
.text
.globl main
.type main,@function

main:
pushq %rbp
movq %rsp, %rbp

#pass parameters and call other functions
movl sizeIntArrays, %edi #move size to registers for 1st parameter
leaq intArray1, %rsi #load effective address of intArray1 to register rsi
leaq intArray2, %rdx #load effective address of intArray2 to register rdx
call multInts #call multInts function

movq $0, %rax #return 0 to caller

movq %rbp, %rsp
popq %rbp
ret
.size main,.-main


##### MULTINTS
.globl multInts
.type multInts,@function

multInts:
pushq %rbp
movq %rsp, %rbp

#add code here for what the functions should do
movq $0, %r8 #initialize index for array access in caller save reg
movq $0, %rcx #initialize 8 byte caller save result reg

loop0:
cmpl %r8d, %edi #compare index to size
je exit0 #exit if equal
movslq (%rsi,%r8,4),%rax # Load a long into RAX
movslq (%rdx,%r8,4),%r11 # Load a long into R11
imulq %r11, %rax # RAX *= R11
addq %rax, %rcx # RCX += RAX
incq %r8 #increment index
jmp loop0

exit0:
movq $.LC0, %rdi
movq %rcx, %rsi
movq $0, %rax

call printf

movq %rbp, %rsp
popq %rbp
ret
.size multInts,.-multInts


What I've tried to do is just move the printf instruction to before the loop, but it gives me a segmentation fault when trying to run the loop because %rdi and %rsi contain the addresses of the arrays that need to be used in the loop. How do I get around that and which registers should I use? Also, how do I call printf within the loop?



The output should look something like this:



Products:
200
-925
1386
-2928
-520









share|improve this question



























    1















    I'm having trouble figuring out how to use printf correctly in this function. So the function is called multInts and is supposed to multiply the first element of the first array with the first element of the second array and continue through the whole array. However, the lab instructions specify that I can't call printf in the main function. So, I need to print out the word "Products:n" and then in each new line after that, print out the product. I don't know how to use printf within the loop, however. The instructor said that we should "call printf in the loop after calculating product" and also to "save and restore caller-save registers before calling printf," but I'm not sure what that means.
    Here's what my code looks like so far:



    .file   "lab4.s"
    .section .rodata

    .LC0:
    .string "Products: n"
    .LC1:
    .string "%i n"
    .data
    sizeIntArrays:
    .long 5
    sizeShortArrays:
    .word 4
    intArray1:
    .long 10
    .long 25
    .long 33
    .long 48
    .long 52
    intArray2:
    .long 20
    .long -37
    .long 42
    .long -61
    .long -10

    ##### MAIN FUNCTION
    .text
    .globl main
    .type main,@function

    main:
    pushq %rbp
    movq %rsp, %rbp

    #pass parameters and call other functions
    movl sizeIntArrays, %edi #move size to registers for 1st parameter
    leaq intArray1, %rsi #load effective address of intArray1 to register rsi
    leaq intArray2, %rdx #load effective address of intArray2 to register rdx
    call multInts #call multInts function

    movq $0, %rax #return 0 to caller

    movq %rbp, %rsp
    popq %rbp
    ret
    .size main,.-main


    ##### MULTINTS
    .globl multInts
    .type multInts,@function

    multInts:
    pushq %rbp
    movq %rsp, %rbp

    #add code here for what the functions should do
    movq $0, %r8 #initialize index for array access in caller save reg
    movq $0, %rcx #initialize 8 byte caller save result reg

    loop0:
    cmpl %r8d, %edi #compare index to size
    je exit0 #exit if equal
    movslq (%rsi,%r8,4),%rax # Load a long into RAX
    movslq (%rdx,%r8,4),%r11 # Load a long into R11
    imulq %r11, %rax # RAX *= R11
    addq %rax, %rcx # RCX += RAX
    incq %r8 #increment index
    jmp loop0

    exit0:
    movq $.LC0, %rdi
    movq %rcx, %rsi
    movq $0, %rax

    call printf

    movq %rbp, %rsp
    popq %rbp
    ret
    .size multInts,.-multInts


    What I've tried to do is just move the printf instruction to before the loop, but it gives me a segmentation fault when trying to run the loop because %rdi and %rsi contain the addresses of the arrays that need to be used in the loop. How do I get around that and which registers should I use? Also, how do I call printf within the loop?



    The output should look something like this:



    Products:
    200
    -925
    1386
    -2928
    -520









    share|improve this question

























      1












      1








      1








      I'm having trouble figuring out how to use printf correctly in this function. So the function is called multInts and is supposed to multiply the first element of the first array with the first element of the second array and continue through the whole array. However, the lab instructions specify that I can't call printf in the main function. So, I need to print out the word "Products:n" and then in each new line after that, print out the product. I don't know how to use printf within the loop, however. The instructor said that we should "call printf in the loop after calculating product" and also to "save and restore caller-save registers before calling printf," but I'm not sure what that means.
      Here's what my code looks like so far:



      .file   "lab4.s"
      .section .rodata

      .LC0:
      .string "Products: n"
      .LC1:
      .string "%i n"
      .data
      sizeIntArrays:
      .long 5
      sizeShortArrays:
      .word 4
      intArray1:
      .long 10
      .long 25
      .long 33
      .long 48
      .long 52
      intArray2:
      .long 20
      .long -37
      .long 42
      .long -61
      .long -10

      ##### MAIN FUNCTION
      .text
      .globl main
      .type main,@function

      main:
      pushq %rbp
      movq %rsp, %rbp

      #pass parameters and call other functions
      movl sizeIntArrays, %edi #move size to registers for 1st parameter
      leaq intArray1, %rsi #load effective address of intArray1 to register rsi
      leaq intArray2, %rdx #load effective address of intArray2 to register rdx
      call multInts #call multInts function

      movq $0, %rax #return 0 to caller

      movq %rbp, %rsp
      popq %rbp
      ret
      .size main,.-main


      ##### MULTINTS
      .globl multInts
      .type multInts,@function

      multInts:
      pushq %rbp
      movq %rsp, %rbp

      #add code here for what the functions should do
      movq $0, %r8 #initialize index for array access in caller save reg
      movq $0, %rcx #initialize 8 byte caller save result reg

      loop0:
      cmpl %r8d, %edi #compare index to size
      je exit0 #exit if equal
      movslq (%rsi,%r8,4),%rax # Load a long into RAX
      movslq (%rdx,%r8,4),%r11 # Load a long into R11
      imulq %r11, %rax # RAX *= R11
      addq %rax, %rcx # RCX += RAX
      incq %r8 #increment index
      jmp loop0

      exit0:
      movq $.LC0, %rdi
      movq %rcx, %rsi
      movq $0, %rax

      call printf

      movq %rbp, %rsp
      popq %rbp
      ret
      .size multInts,.-multInts


      What I've tried to do is just move the printf instruction to before the loop, but it gives me a segmentation fault when trying to run the loop because %rdi and %rsi contain the addresses of the arrays that need to be used in the loop. How do I get around that and which registers should I use? Also, how do I call printf within the loop?



      The output should look something like this:



      Products:
      200
      -925
      1386
      -2928
      -520









      share|improve this question














      I'm having trouble figuring out how to use printf correctly in this function. So the function is called multInts and is supposed to multiply the first element of the first array with the first element of the second array and continue through the whole array. However, the lab instructions specify that I can't call printf in the main function. So, I need to print out the word "Products:n" and then in each new line after that, print out the product. I don't know how to use printf within the loop, however. The instructor said that we should "call printf in the loop after calculating product" and also to "save and restore caller-save registers before calling printf," but I'm not sure what that means.
      Here's what my code looks like so far:



      .file   "lab4.s"
      .section .rodata

      .LC0:
      .string "Products: n"
      .LC1:
      .string "%i n"
      .data
      sizeIntArrays:
      .long 5
      sizeShortArrays:
      .word 4
      intArray1:
      .long 10
      .long 25
      .long 33
      .long 48
      .long 52
      intArray2:
      .long 20
      .long -37
      .long 42
      .long -61
      .long -10

      ##### MAIN FUNCTION
      .text
      .globl main
      .type main,@function

      main:
      pushq %rbp
      movq %rsp, %rbp

      #pass parameters and call other functions
      movl sizeIntArrays, %edi #move size to registers for 1st parameter
      leaq intArray1, %rsi #load effective address of intArray1 to register rsi
      leaq intArray2, %rdx #load effective address of intArray2 to register rdx
      call multInts #call multInts function

      movq $0, %rax #return 0 to caller

      movq %rbp, %rsp
      popq %rbp
      ret
      .size main,.-main


      ##### MULTINTS
      .globl multInts
      .type multInts,@function

      multInts:
      pushq %rbp
      movq %rsp, %rbp

      #add code here for what the functions should do
      movq $0, %r8 #initialize index for array access in caller save reg
      movq $0, %rcx #initialize 8 byte caller save result reg

      loop0:
      cmpl %r8d, %edi #compare index to size
      je exit0 #exit if equal
      movslq (%rsi,%r8,4),%rax # Load a long into RAX
      movslq (%rdx,%r8,4),%r11 # Load a long into R11
      imulq %r11, %rax # RAX *= R11
      addq %rax, %rcx # RCX += RAX
      incq %r8 #increment index
      jmp loop0

      exit0:
      movq $.LC0, %rdi
      movq %rcx, %rsi
      movq $0, %rax

      call printf

      movq %rbp, %rsp
      popq %rbp
      ret
      .size multInts,.-multInts


      What I've tried to do is just move the printf instruction to before the loop, but it gives me a segmentation fault when trying to run the loop because %rdi and %rsi contain the addresses of the arrays that need to be used in the loop. How do I get around that and which registers should I use? Also, how do I call printf within the loop?



      The output should look something like this:



      Products:
      200
      -925
      1386
      -2928
      -520






      arrays assembly printf x86-64






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 26 '18 at 2:28









      AishaAisha

      184




      184
























          2 Answers
          2






          active

          oldest

          votes


















          1














          The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:



          pushq %rax
          pushq %rdx
          pushq %rsi
          pushq %rdi
          pushq %r8
          pushq %r11
          movq $.LC1, %rdi
          movq %rax, %rsi
          movq $0, %rax
          call printf
          popq %r11
          popq %r8
          popq %rdi
          popq %rsi
          popq %rdx
          popq %rax


          Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:



          ...
          multInts:
          pushq %rbp
          movq %rsp, %rbp

          #add code here for what the functions should do

          pushq %rdx # Preserve registers
          pushq %rdi
          pushq %rsi
          movq $.LC0, %rdi # Format string (no further values)
          movq $0, %rax # No vector registers used
          call printf # Call C function
          popq %rsi # Restore registers
          popq %rdi
          popq %rdx

          movq $0, %r8 #initialize index for array access in caller save reg

          loop0:
          cmpl %r8d, %edi #compare index to size
          je exit0 #exit if equal

          movslq (%rsi,%r8,4),%rax # Load a long into RAX
          movslq (%rdx,%r8,4),%r11 # Load a long into R11
          imulq %r11, %rax # RAX *= R11

          pushq %rax # Preserve registers
          pushq %rdx
          pushq %rsi
          pushq %rdi
          pushq %r8
          pushq %r11
          movq $.LC1, %rdi # Format string
          movq %rax, %rsi # Value
          movq $0, %rax # No vector registers used
          call printf # Call C function
          popq %r11 # Restore registers
          popq %r8
          popq %rdi
          popq %rsi
          popq %rdx
          popq %rax

          incq %r8 #increment index
          jmp loop0

          exit0:

          movq %rbp, %rsp
          popq %rbp
          ret
          ...


          BTW: .string "%i n" will force printf only to process the lower 32-bit of RDI. Use .string %lli n instead.






          share|improve this answer































            1














            Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.



            Look at compiler output for an example: write a version of your loop in C and compile it with -Og.



            Obviously you need to move the instructions that set up the args in registers
            (like the format string) along with the call printf.






            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474035%2fusing-printf-before-and-inside-a-loop-x86-64-assembly%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1














              The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:



              pushq %rax
              pushq %rdx
              pushq %rsi
              pushq %rdi
              pushq %r8
              pushq %r11
              movq $.LC1, %rdi
              movq %rax, %rsi
              movq $0, %rax
              call printf
              popq %r11
              popq %r8
              popq %rdi
              popq %rsi
              popq %rdx
              popq %rax


              Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:



              ...
              multInts:
              pushq %rbp
              movq %rsp, %rbp

              #add code here for what the functions should do

              pushq %rdx # Preserve registers
              pushq %rdi
              pushq %rsi
              movq $.LC0, %rdi # Format string (no further values)
              movq $0, %rax # No vector registers used
              call printf # Call C function
              popq %rsi # Restore registers
              popq %rdi
              popq %rdx

              movq $0, %r8 #initialize index for array access in caller save reg

              loop0:
              cmpl %r8d, %edi #compare index to size
              je exit0 #exit if equal

              movslq (%rsi,%r8,4),%rax # Load a long into RAX
              movslq (%rdx,%r8,4),%r11 # Load a long into R11
              imulq %r11, %rax # RAX *= R11

              pushq %rax # Preserve registers
              pushq %rdx
              pushq %rsi
              pushq %rdi
              pushq %r8
              pushq %r11
              movq $.LC1, %rdi # Format string
              movq %rax, %rsi # Value
              movq $0, %rax # No vector registers used
              call printf # Call C function
              popq %r11 # Restore registers
              popq %r8
              popq %rdi
              popq %rsi
              popq %rdx
              popq %rax

              incq %r8 #increment index
              jmp loop0

              exit0:

              movq %rbp, %rsp
              popq %rbp
              ret
              ...


              BTW: .string "%i n" will force printf only to process the lower 32-bit of RDI. Use .string %lli n instead.






              share|improve this answer




























                1














                The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:



                pushq %rax
                pushq %rdx
                pushq %rsi
                pushq %rdi
                pushq %r8
                pushq %r11
                movq $.LC1, %rdi
                movq %rax, %rsi
                movq $0, %rax
                call printf
                popq %r11
                popq %r8
                popq %rdi
                popq %rsi
                popq %rdx
                popq %rax


                Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:



                ...
                multInts:
                pushq %rbp
                movq %rsp, %rbp

                #add code here for what the functions should do

                pushq %rdx # Preserve registers
                pushq %rdi
                pushq %rsi
                movq $.LC0, %rdi # Format string (no further values)
                movq $0, %rax # No vector registers used
                call printf # Call C function
                popq %rsi # Restore registers
                popq %rdi
                popq %rdx

                movq $0, %r8 #initialize index for array access in caller save reg

                loop0:
                cmpl %r8d, %edi #compare index to size
                je exit0 #exit if equal

                movslq (%rsi,%r8,4),%rax # Load a long into RAX
                movslq (%rdx,%r8,4),%r11 # Load a long into R11
                imulq %r11, %rax # RAX *= R11

                pushq %rax # Preserve registers
                pushq %rdx
                pushq %rsi
                pushq %rdi
                pushq %r8
                pushq %r11
                movq $.LC1, %rdi # Format string
                movq %rax, %rsi # Value
                movq $0, %rax # No vector registers used
                call printf # Call C function
                popq %r11 # Restore registers
                popq %r8
                popq %rdi
                popq %rsi
                popq %rdx
                popq %rax

                incq %r8 #increment index
                jmp loop0

                exit0:

                movq %rbp, %rsp
                popq %rbp
                ret
                ...


                BTW: .string "%i n" will force printf only to process the lower 32-bit of RDI. Use .string %lli n instead.






                share|improve this answer


























                  1












                  1








                  1







                  The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:



                  pushq %rax
                  pushq %rdx
                  pushq %rsi
                  pushq %rdi
                  pushq %r8
                  pushq %r11
                  movq $.LC1, %rdi
                  movq %rax, %rsi
                  movq $0, %rax
                  call printf
                  popq %r11
                  popq %r8
                  popq %rdi
                  popq %rsi
                  popq %rdx
                  popq %rax


                  Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:



                  ...
                  multInts:
                  pushq %rbp
                  movq %rsp, %rbp

                  #add code here for what the functions should do

                  pushq %rdx # Preserve registers
                  pushq %rdi
                  pushq %rsi
                  movq $.LC0, %rdi # Format string (no further values)
                  movq $0, %rax # No vector registers used
                  call printf # Call C function
                  popq %rsi # Restore registers
                  popq %rdi
                  popq %rdx

                  movq $0, %r8 #initialize index for array access in caller save reg

                  loop0:
                  cmpl %r8d, %edi #compare index to size
                  je exit0 #exit if equal

                  movslq (%rsi,%r8,4),%rax # Load a long into RAX
                  movslq (%rdx,%r8,4),%r11 # Load a long into R11
                  imulq %r11, %rax # RAX *= R11

                  pushq %rax # Preserve registers
                  pushq %rdx
                  pushq %rsi
                  pushq %rdi
                  pushq %r8
                  pushq %r11
                  movq $.LC1, %rdi # Format string
                  movq %rax, %rsi # Value
                  movq $0, %rax # No vector registers used
                  call printf # Call C function
                  popq %r11 # Restore registers
                  popq %r8
                  popq %rdi
                  popq %rsi
                  popq %rdx
                  popq %rax

                  incq %r8 #increment index
                  jmp loop0

                  exit0:

                  movq %rbp, %rsp
                  popq %rbp
                  ret
                  ...


                  BTW: .string "%i n" will force printf only to process the lower 32-bit of RDI. Use .string %lli n instead.






                  share|improve this answer













                  The easiest way to protect a register from being accessed by a subroutine is to push it. According to the ABI V calling convention printf may change any register except RBX, RBP, R12–R15. The registers you need to preserve are RAX, RDX, RSI, RDI, R8 and R11 (RCX is no longer needed), so push before the call to printf and pop them afterwards:



                  pushq %rax
                  pushq %rdx
                  pushq %rsi
                  pushq %rdi
                  pushq %r8
                  pushq %r11
                  movq $.LC1, %rdi
                  movq %rax, %rsi
                  movq $0, %rax
                  call printf
                  popq %r11
                  popq %r8
                  popq %rdi
                  popq %rsi
                  popq %rdx
                  popq %rax


                  Now, you can copy the block into the loop. For each printf, you have to think about what needs to be secured:



                  ...
                  multInts:
                  pushq %rbp
                  movq %rsp, %rbp

                  #add code here for what the functions should do

                  pushq %rdx # Preserve registers
                  pushq %rdi
                  pushq %rsi
                  movq $.LC0, %rdi # Format string (no further values)
                  movq $0, %rax # No vector registers used
                  call printf # Call C function
                  popq %rsi # Restore registers
                  popq %rdi
                  popq %rdx

                  movq $0, %r8 #initialize index for array access in caller save reg

                  loop0:
                  cmpl %r8d, %edi #compare index to size
                  je exit0 #exit if equal

                  movslq (%rsi,%r8,4),%rax # Load a long into RAX
                  movslq (%rdx,%r8,4),%r11 # Load a long into R11
                  imulq %r11, %rax # RAX *= R11

                  pushq %rax # Preserve registers
                  pushq %rdx
                  pushq %rsi
                  pushq %rdi
                  pushq %r8
                  pushq %r11
                  movq $.LC1, %rdi # Format string
                  movq %rax, %rsi # Value
                  movq $0, %rax # No vector registers used
                  call printf # Call C function
                  popq %r11 # Restore registers
                  popq %r8
                  popq %rdi
                  popq %rsi
                  popq %rdx
                  popq %rax

                  incq %r8 #increment index
                  jmp loop0

                  exit0:

                  movq %rbp, %rsp
                  popq %rbp
                  ret
                  ...


                  BTW: .string "%i n" will force printf only to process the lower 32-bit of RDI. Use .string %lli n instead.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 26 '18 at 19:27









                  rkhbrkhb

                  11.4k72142




                  11.4k72142

























                      1














                      Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.



                      Look at compiler output for an example: write a version of your loop in C and compile it with -Og.



                      Obviously you need to move the instructions that set up the args in registers
                      (like the format string) along with the call printf.






                      share|improve this answer




























                        1














                        Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.



                        Look at compiler output for an example: write a version of your loop in C and compile it with -Og.



                        Obviously you need to move the instructions that set up the args in registers
                        (like the format string) along with the call printf.






                        share|improve this answer


























                          1












                          1








                          1







                          Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.



                          Look at compiler output for an example: write a version of your loop in C and compile it with -Og.



                          Obviously you need to move the instructions that set up the args in registers
                          (like the format string) along with the call printf.






                          share|improve this answer













                          Assume that printf clobbers all the call-clobbered registers (What registers are preserved through a linux x86-64 function call), and use different ones for anything that needs to survive from one iteration of the loop to the next.



                          Look at compiler output for an example: write a version of your loop in C and compile it with -Og.



                          Obviously you need to move the instructions that set up the args in registers
                          (like the format string) along with the call printf.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 26 '18 at 2:43









                          Peter CordesPeter Cordes

                          130k18196334




                          130k18196334






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53474035%2fusing-printf-before-and-inside-a-loop-x86-64-assembly%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              404 Error Contact Form 7 ajax form submitting

                              How to know if a Active Directory user can login interactively

                              TypeError: fit_transform() missing 1 required positional argument: 'X'