nasm汇编调用C库

Linux x86-64 与 printf

主程序

default rel            ; make [rel format] the default, you always want this.
extern printf, exit    ; NASM requires declarations of external symbols, unlike GAS
section .rodata
    format db "%#x", 10, 0   ; C 0-terminated string: "%#x\n" 
section .text
global main
main:
    sub   rsp, 8             ; re-align the stack to 16 before calling another function

    ; Call printf.
    mov   esi, 0x12345678    ; "%x" takes a 32-bit unsigned int
    lea   rdi, [rel format]
    xor   eax, eax           ; AL=0  no FP args in XMM regs
    call  printf

    ; Return from main.
    xor   eax, eax
    add   rsp, 8
    ret

GitHub 上游.

然后:

nasm -f elf64 -o main.o main.asm
gcc -no-pie -o main.out main.o
./main.out

输出:

0x12345678

why -no-pie ?

How to compile nasm program calling printf? [duplicate]
Asked 1 year, 4 months ago
Modified 1 year, 4 months ago
Viewed 896 times

1

This question already has answers here:
Can’t call C standard library function on 64-bit Linux from assembly (yasm) code (2 answers)
How to print a number in assembly NASM? (6 answers)
Closed last year.

https://cs.lmu.edu/~ray/notes/nasmtutorial/

I got the following error when I try to compile fib.asm on Linux. Could you let me know how to compile it? Thanks.

$ nasm -felf64 fib.asm && gcc fib.o && ./a.out
/usr/bin/ld: fib.o: warning: relocation in read-only section `.text'
/usr/bin/ld: fib.o: relocation R_X86_64_PC32 against symbol `printf@@GLIBC_2.2.5' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

3
Provide -no-pie to the gcc command to fix this problem. Modern Linux systems default to PIE which many tutorials unfortunately don’t cover. Turning off PIE makes the tutorial work again. –
fuz
Jan 27, 2021 at 3:03
1
You’re right, 32-bit absolute addresses no longer allowed in x86-64 Linux? is more about data accesses like [symbol + rdi], not about the fact that function calls don’t implicitly turn call foo into call foo wrt …plt for you when linking a PIE, only a normal executable. I picked that duplicate first because it’s about PIEs and how that’s now the default (and it mentions -no-pie), but the other Q&As I later added to the top of the duplicate list are much more exact fits, and discuss exactly how to call functions in shared libraries like libc. –
Peter Cordes
Jan 27, 2021 at 3:29
My answer on Can’t call C standard library function on 64-bit Linux from assembly (yasm) code and Ciro’s answer on How to print a number in assembly NASM? both clearly explain what’s going on, and that -no-pie is the easy way, or how to write NASM syntax that works in a PIE. My answer also tries to explain why it doesn’t work when you do it this way, but Ciro’s is more of a simple recipe that’s easier to follow. Both are useful for different reasons, but each sufficient on its own, so I linked both duplicates. –
Peter Cordes
Jan 27, 2021 at 3:44
But why the webpage clearly say nasm -felf64 fib.asm && gcc fib.o && ./a.out works. Does it work in some cases that you are not aware of? How can you be sure your answers cover 100% of the cases? –
user1424739
Jan 27, 2021 at 3:46
1
Because it’s an old tutorial. As 32-bit absolute addresses no longer allowed in x86-64 Linux? explained, Linux distros changes to making -fPIE -pie the default in about 2017, where it wasn’t before, to enable ASLR for sections other than the stack. This fully explains 100% of what you’re seeing, including that exact error message, and why the tutorial didn’t use that option or PIE-compatible asm. (And that explanation is part of why I originally linked that as one of the duplicates.) –
Peter Cordes
Jan 27, 2021 at 3:53
Could you just show the commands that can compile and liink the nasm file? the link that you post is not minimal. I first need a command that is working. –
user1424739
Jan 27, 2021 at 3:57
BTW, that tutorial looks fairly good, but randomly uses lea rdi, [rel message] (good) in some examples vs. mov rdi, message (inefficient) in others, including otherwise-equivalent Linux vs. MacOS puts examples which makes it look like one is the Linux way, one is the MacOS way. That’s not true. How to load address of function or label into register –
Peter Cordes
Jan 27, 2021 at 3:57
Come on dude, if you just want something that works, have you not yet tried fuz’s comment to use gcc -no-pie fib.o? That will work exactly the way it did when the tutorial was written, letting the code from those tutorials work. –
Peter Cordes
Jan 27, 2021 at 3:59
OK. It works. I think you should just post gcc -no-pie -o fib.exe fib.o as an answer. My question is “how …”? The answer is just a command that works. Instead, you posted too many previous answers that do not directly answer my questions. If you really want to link to those previous questions, you should first provide a working command then provide these previous answers to explain why the command works, rather than just provide links to those previous questions which does not directly answer my question. We are just wasting too much text on this simple question. –
user1424739
Jan 27, 2021 at 4:03

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

barbyQAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值