【发布时间】:2015-04-23 17:26:13
【问题描述】:
我正在尝试遵循我在博客上找到的示例。
androideabi 似乎不能直接在汇编代码级别调用 printf (可能我在编译时遗漏了一个标志?)。
我正在使用这些命令运行:
arm-linux-androideabi-as -o fib.o fibonacci.s
arm-linux-androideabi-ld --sysroot $env:SYSROOT -s -o fib fib.o
fib.o(.text+0x8): error: undefined reference to 'printf'
我从汇编代码中得到一个未定义的引用。
如果它真的成功了,那就太好了。如果有人想分享他们对低级编程的真棒知识,我当然愿意接受替代解决方案!
对于这个问题有什么建议吗?代码如下:
.syntax unified
.equ maxfib,4000000
previous .req r4
current .req r5
next .req r6
sum .req r7
max .req r8
tmp .req r9
.section .rodata
.align 2
fibstring:
.asciz "fib is %d\n"
sumstring:
.asciz "%d\n"
len = . - sumstring
.text
.align 2
.global main
.extern printf
.type main, %function
main:
stmfd sp!, {r4-r9, lr}
ldr max, =maxfib
mov previous, 1
mov current, 1
mov sum, 0
loop:
cmp current, max
bgt last
add next, current, previous
movs tmp, current, lsr 1 @ set carry flag from lsr - for the odd-valued terms
@ we discard the result of the movs and are only interested
@ in the side effect of the lsr which pushes the lower bit
@ of current (1 for odd; 0 for even) into the carry flag
@ movs will update the status register (c.f. mov which will not)
addcc sum, sum, current @ we add current to the sum ONLY when cc (carry clear) is true
@ these are even-valued fibonacci terms
mov previous, current
mov current, next
b loop
last:
mov r1, sum
ldr r0, =sumstring @ store address of start of string to r0
bl printf
mov r0, 0
ldmfd sp!, {r4-r9, pc}
mov r7, 1 @ set r7 to 1 - the syscall for exit
swi 0 @ then invoke the syscall from linux
【问题讨论】:
-
链接器不是通灵的——你需要给它一个带有
printf的库。当直接进入汇编器和链接器而不是通过编译器时,预计必须做所有的事情编译器会(通常)自动为你做。 -
尝试直接使用 gcc 而不是 as, ld 组合。指定 sysroot 后它应该可以工作,但当然这并不意味着您的代码是正确的。
-
试过了:arm-linux-androideabi-gcc-4.9 -fPIE -pie --sysroot $env:SYSROOT -s -o fib fib.o 我得到了;警告:链接器:./fib 有文本重定位。这会浪费内存并防止安全加固。请修复。 4613732
-
我的意思是使用 gcc 到 .s -> 可执行文件。它可能会修复该警告。如果不是组装,则不遵循最佳实践,那是另一个问题。
标签: android assembly android-ndk arm