Getting undefined reference to “printf” error for assembly code despite using gcc linker









up vote
1
down vote

favorite












I am trying to follow the exercise in the book PC Assembly by Paul Carter. http://pacman128.github.io/pcasm/



I'm trying to run the program from 1.4 page 23 on Ubuntu 18. The files are all available on the github site above.



Since original code is for 32bit I compile using



nasm -f elf32



for first.asm and asm_io.asm to get the object files. I also compile driver.c



I use the linker from gcc and run



gcc -m32 -o first first.o asm_io.o driver.o 


but it keeps giving me a bun of errors like



undefined reference to '_scanf'
undefined reference to '_printf'



(note _printf appears instead of printf because some conversion is done in the file asm_io.asm to maintain compatibility between windows and linux OS's)



I don't know why these errors are appearing. I also try running using linker directly



ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2 


and many variations since it seems that its not linking with the C libraries.



Any help? Stuck on this for a while and couldn't find a solution on similar questions










share|improve this question



























    up vote
    1
    down vote

    favorite












    I am trying to follow the exercise in the book PC Assembly by Paul Carter. http://pacman128.github.io/pcasm/



    I'm trying to run the program from 1.4 page 23 on Ubuntu 18. The files are all available on the github site above.



    Since original code is for 32bit I compile using



    nasm -f elf32



    for first.asm and asm_io.asm to get the object files. I also compile driver.c



    I use the linker from gcc and run



    gcc -m32 -o first first.o asm_io.o driver.o 


    but it keeps giving me a bun of errors like



    undefined reference to '_scanf'
    undefined reference to '_printf'



    (note _printf appears instead of printf because some conversion is done in the file asm_io.asm to maintain compatibility between windows and linux OS's)



    I don't know why these errors are appearing. I also try running using linker directly



    ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2 


    and many variations since it seems that its not linking with the C libraries.



    Any help? Stuck on this for a while and couldn't find a solution on similar questions










    share|improve this question

























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am trying to follow the exercise in the book PC Assembly by Paul Carter. http://pacman128.github.io/pcasm/



      I'm trying to run the program from 1.4 page 23 on Ubuntu 18. The files are all available on the github site above.



      Since original code is for 32bit I compile using



      nasm -f elf32



      for first.asm and asm_io.asm to get the object files. I also compile driver.c



      I use the linker from gcc and run



      gcc -m32 -o first first.o asm_io.o driver.o 


      but it keeps giving me a bun of errors like



      undefined reference to '_scanf'
      undefined reference to '_printf'



      (note _printf appears instead of printf because some conversion is done in the file asm_io.asm to maintain compatibility between windows and linux OS's)



      I don't know why these errors are appearing. I also try running using linker directly



      ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2 


      and many variations since it seems that its not linking with the C libraries.



      Any help? Stuck on this for a while and couldn't find a solution on similar questions










      share|improve this question















      I am trying to follow the exercise in the book PC Assembly by Paul Carter. http://pacman128.github.io/pcasm/



      I'm trying to run the program from 1.4 page 23 on Ubuntu 18. The files are all available on the github site above.



      Since original code is for 32bit I compile using



      nasm -f elf32



      for first.asm and asm_io.asm to get the object files. I also compile driver.c



      I use the linker from gcc and run



      gcc -m32 -o first first.o asm_io.o driver.o 


      but it keeps giving me a bun of errors like



      undefined reference to '_scanf'
      undefined reference to '_printf'



      (note _printf appears instead of printf because some conversion is done in the file asm_io.asm to maintain compatibility between windows and linux OS's)



      I don't know why these errors are appearing. I also try running using linker directly



      ld -m elf_i386 -e main -o first -first.o driver.o asm_io.o -I /lib/i386-linux-gnu/ld-linux.so.2 


      and many variations since it seems that its not linking with the C libraries.



      Any help? Stuck on this for a while and couldn't find a solution on similar questions







      linux assembly x86 linker nasm






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 days ago









      Peter Cordes

      114k16171294




      114k16171294










      asked 2 days ago









      ackbar03

      253




      253






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.



          So call printf, not _printf, because there is no _printf in libc.



          Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.



          So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.




          Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.




          Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.



          They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:



          %ifidn __OUTPUT_FORMAT__, elf32
          %define ELF_TYPE 32
          %elifidn __OUTPUT_FORMAT__, elf64
          %define ELF_TYPE 64
          %endif


          %ifdef ELF_TYPE
          ...
          %endif





          share|improve this answer


















          • 1




            I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
            – ackbar03
            2 days ago











          • @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
            – Peter Cordes
            2 days ago










          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',
          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%2f53237752%2fgetting-undefined-reference-to-printf-error-for-assembly-code-despite-using-gc%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.



          So call printf, not _printf, because there is no _printf in libc.



          Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.



          So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.




          Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.




          Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.



          They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:



          %ifidn __OUTPUT_FORMAT__, elf32
          %define ELF_TYPE 32
          %elifidn __OUTPUT_FORMAT__, elf64
          %define ELF_TYPE 64
          %endif


          %ifdef ELF_TYPE
          ...
          %endif





          share|improve this answer


















          • 1




            I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
            – ackbar03
            2 days ago











          • @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
            – Peter Cordes
            2 days ago














          up vote
          4
          down vote



          accepted










          Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.



          So call printf, not _printf, because there is no _printf in libc.



          Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.



          So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.




          Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.




          Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.



          They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:



          %ifidn __OUTPUT_FORMAT__, elf32
          %define ELF_TYPE 32
          %elifidn __OUTPUT_FORMAT__, elf64
          %define ELF_TYPE 64
          %endif


          %ifdef ELF_TYPE
          ...
          %endif





          share|improve this answer


















          • 1




            I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
            – ackbar03
            2 days ago











          • @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
            – Peter Cordes
            2 days ago












          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.



          So call printf, not _printf, because there is no _printf in libc.



          Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.



          So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.




          Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.




          Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.



          They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:



          %ifidn __OUTPUT_FORMAT__, elf32
          %define ELF_TYPE 32
          %elifidn __OUTPUT_FORMAT__, elf64
          %define ELF_TYPE 64
          %endif


          %ifdef ELF_TYPE
          ...
          %endif





          share|improve this answer














          Linux doesn't prepend _ to names when mapping from C to asm symbol names in ELF object files1.



          So call printf, not _printf, because there is no _printf in libc.



          Whatever "compatibility" code did that is doing it wrong. Only Windows and OS X use _printf, Linux uses printf.



          So either you've misconfigured something or defined the wrong setting, or it requires updating / porting to Linux.




          Footnote 1: In ancient history (like over 20 years ago), Linux with the a.out file format did use leading underscores on symbol names.




          Update: the library uses the NASM preprocessor to %define _scanf scanf and so on, but it requires you to manually define ELF_TYPE by assembling with nasm -d ELF_TYPE.



          They could have detected ELF32 or ELF64 output formats on their own, because NASM pre-defines __OUTPUT_FORMAT__. Someone should submit a pull-request to make this detection automatic with code something like this:



          %ifidn __OUTPUT_FORMAT__, elf32
          %define ELF_TYPE 32
          %elifidn __OUTPUT_FORMAT__, elf64
          %define ELF_TYPE 64
          %endif


          %ifdef ELF_TYPE
          ...
          %endif






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 days ago

























          answered 2 days ago









          Peter Cordes

          114k16171294




          114k16171294







          • 1




            I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
            – ackbar03
            2 days ago











          • @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
            – Peter Cordes
            2 days ago












          • 1




            I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
            – ackbar03
            2 days ago











          • @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
            – Peter Cordes
            2 days ago







          1




          1




          I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
          – ackbar03
          2 days ago





          I was just gonna point out that in the asm_io.asm file the author included (includes some functions used for debugging) it has a section %ifdef ELF_TYPE %define _scanf scanf %define _printf printf but then I took a closer look and in the comments it said to compile with nasm -f elf -d ELF_TYPE asm_io.asm and uh... yea that solved the problem lol, stupid me. So i guess thanks haha, and for the very prompt answer. I'll put this as the right answer
          – ackbar03
          2 days ago













          @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
          – Peter Cordes
          2 days ago




          @ackbar03: They could have used %ifidn __OUTPUT_FORMAT__, elf32 (and also check for elf64) to avoid you having to manually do anything on the NASM command line. Someone should send in a pull request. How to detect architecture in NASM at compile time to have one source code for both x64 and x86?
          – Peter Cordes
          2 days ago

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237752%2fgetting-undefined-reference-to-printf-error-for-assembly-code-despite-using-gc%23new-answer', 'question_page');

          );

          Post as a guest














































































          Popular posts from this blog

          Top Tejano songwriter Luis Silva dead of heart attack at 64

          ReactJS Fetched API data displays live - need Data displayed static

          政党