在不丢失 .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 的正确标志是啥的主要内容,如果未能解决你的问题,请参考以下文章

C#在不丢失数据的情况下在页面之间导航

在不丢失数据的情况下处理屏幕旋转 - Android

keil4 下 c语言和汇编语言。混合编程的方法。

如何在不丢失数据点顺序的情况下将 Pandas 中的字符串列表分解为单个列表

最近在搞C\C++ 和汇编语言 的混合编程,如何讲2者在编译环境中连接起来。

在不丢失 Html 样式的情况下更改 NSAttributedString 中的字体大小 - Swift