在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是啥
Posted
技术标签:
【中文标题】在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是啥【英文标题】:what are the correct flags to mix assembly and C without losing .data constants在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是什么 【发布时间】:2020-11-26 08:42:53 【问题描述】:我正在开发一个从 C 调用的汇编程序(x86、NASM 2.13、gcc 7.50、Ubuntu 18.X)中的实用程序。我遇到的问题是字符串常量地址似乎在制作过程,所以消息不打印。我可以在最终的二进制文件中看到字符串常量。
这是示例汇编代码
SECTION .data
error_len_message: db "test", 10
error_len_message_len: equ $-error_len_message
SECTION .text
global test_func
test_func:
mov eax, 4
mov ebx, 1
mov ecx, error_len_message
mov edx, error_len_message_len
int 80H
头文件很简单,因为它只需要 main.c 中使用的签名
#include "....."
int main(void)
test_func();
return 0;
可执行文件的make文件如下:
util_tests: ../asm/utilities/utilities.o
gcc -Wall -o ./build/$@ main.c $?
../asm/utilities/utilities.o:
cd ../asm/utilities && make && cd ../../util_tests;
clean:
cd ../asm/utilities && make clean && cd ../../util_tests;
实用程序的make文件如下:
utilities.o: test/test.o
ld $? -o $@
test/test.o:
cd test && make && cd ..;
clean:
cd test && make clean && cd ..;
rm *.o
测试汇编代码的make文件是:
test.o: test.asm
nasm -f elf64 -g -F dwarf $?
clean:
rm *.o
仅使用汇编程序并打印 .data 部分中定义的字符串,我可以毫不费力地将其转换为可执行文件。制作文件:
test: test.o
ld -o test $^
test.o: *.asm
nasm -f elf64 -g -F stabs $?
clean:
rm *.o
我可以在 .bss 部分成功定义和使用变量(为简洁起见,未显示)
我认为,问题在于我构建实用程序的方式。提前致谢!
【问题讨论】:
跟踪所有的 makefile 有点困难。你能只显示 make 为了构建它而实际执行的命令吗? 也许您的问题是您在构建 64 位时调用 int80,doesn't always work。 我将在今天晚些时候用 cmets 的建议重新发布这个问题。谢谢! 事实证明,通过使用中间 *.o(实用程序)掩盖了 test.asm 并不是真正的 PIC 的事实。当我尝试按照以前的 cmets 建议进行简化时,链接器抱怨 .data 不可重定位。我将解决这个问题,这解释了为什么 .data 中的标签有奇怪的地址 问题已解决,删除了中间 Makefile 并删除了 int 80H 调用以避免限制。谢谢! 【参考方案1】:因此,在将相关的“默认 rel”添加到汇编程序源文件、删除对 int 80H 的直接调用并添加调用 printf 之后,链接器会失败,因为它还尝试重新定位“printf@glibc_x.x.x”。在尝试链接器选项以忽略未解析的符号后,这似乎是一个死胡同。
所以似乎只有两个选择,在 32 位中组装以避免“int 80H”出现问题,或者返回状态/结果并让调用者处理其余部分。以下 assemble、link 和 gdb 显示正确匹配的标签和偏移量
DEFAULT REL
SECTION .text
global silly
silly:
lea r9, [message]
ret
SECTION .data
message: db "A Message", 10
生成文件:
silly.so: silly.o
ld -shared $? -o $@
silly.o: silly.asm
nasm -f elf64 -g -F dwarf $?
clean:
rm *.o
rm *.so
希望这对任何人都有用
【讨论】:
以上是关于在不丢失 .data 常量的情况下混合汇编和 C 的正确标志是啥的主要内容,如果未能解决你的问题,请参考以下文章
如何在不丢失数据点顺序的情况下将 Pandas 中的字符串列表分解为单个列表