【问题标题】:Assembly Segmentation Fault装配分段错误
【发布时间】:2009-11-30 04:07:25
【问题描述】:

在运行以下汇编代码时遇到错误

#cpuid using C library Functions
.section .data
output:
 .asciz "The Processor Vendor ID is '%s'\n"
.section .bss
 .lcomm buffer, 12
.section .text
.globl main
main:
 movq $0, %rax
 cpuid
 movq $buffer, %rdi
 movq %rbx, (%rdi)
 movq %rdx, (%rdi)
 movq %rcx, (%rdi)
 pushq $buffer
 pushq $output
 call printf
 addq $8, %rsp
 pushq $0
 call exit

在 C 库调用部分遇到分段错误:调用 printf 它以 x86_64 模式运行。 关于 c 库,我在编译 x64 代码时遗漏了什么?还是代码有问题

谢谢

【问题讨论】:

  • 可能希望在这些 movq 之间适当增加 %rdi
  • 谢谢大家,我解决了这个问题。这是我加载的错误库,在我使用 /lib/ld-linux-x86-64.so.2 手动 ld 并用 _start 替换主函数后正常工作。我把它当作动态链接。抱歉英语不好

标签: assembly 64-bit libc


【解决方案1】:

是否调用了 C 运行时库的初始化?必须先运行才能设置标准输出。顺便说一句,堆栈跟踪将消除对问题原因的怀疑。

另外,防止 %s 转换用 %.12s 溢出缓冲区,或者只是在缓冲区后面放一个 NUL 字节。

【讨论】:

    【解决方案2】:

    64 位 fprintf 的汇编程序调用似乎发生了变化,因此要么链接 32 位库,要么使用以下代码:

    #cpuid using C library Functions
    .section .data
    output:
     .asciz "The Processor Vendor ID is '%s'\n"
    .section .bss
     .lcomm buffer, 12
    .section .text
    .globl main
    main:
     movq $0, %rax
     cpuid
     movq $buffer, %rdi
     movq %rbx, (%rdi)
     movq %rdx, 4(%rdi)
     movq %rcx, 8(%rdi)
     movq $buffer, %rsi #1st parameter
     movq $output, %rdi #2nd parameter
     movq $0, %rax
     call printf
     addq $8, %rsp
     pushq $0
     call exit
    

    【讨论】:

    • 你的 movq 指令不会增加(%rdi),所以除非我遗漏了什么,否则movq $buffer, (%rdi) 将在几行之后被你的movq $output, %rdi 覆盖。我可以看到你在做什么,但是为什么要在几行之后将$buffer 复制到%rsi 时使用%rdi
    【解决方案3】:

    不熟悉组装,所以在黑暗中开枪:你的两个字符串都是空终止的吗?

    【讨论】:

    • .asciz 自动添加终止空值。
    【解决方案4】:

    您需要将写入 $buffer 的字符串以空值结尾,而不是在一个单词的顶部写入三遍。另外,wallyk 是对的:您确定 CRT 正在初始化吗?

    老实说,用 C 语言编写这个调用 C 库函数的程序确实要好得多。将 CPUID 代码作为内联汇编写入 __cdecl 函数中,让它将结果写入字符串指针,然后调用该函数来自 C 程序。

    void GetCPUID( char *toStr )
    {
     // inline assembly left as exercise for the reader.. 
     // write ebx to *toStr, ecx to *toStr+4, edx to *toStr+8, and 0 to *toStr+12
    }
    
    void PrintCPUID()
    {
       char cpuidstr[16];
       GetCPUID( cpuidstr );
       printf( "cpuid: %s\n", cpuidstr );
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      相关资源
      最近更新 更多