装配分段故障

时间:2009-11-30 04:07:26

标签: assembly 64-bit libc

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

#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模式运行。 在编译x64代码时,我错过了关于c库的任何内容?或者代码有什么问题

由于

4 个答案:

答案 0 :(得分:4)

是否调用了C运行时库的初始化?必须首先运行才能设置stdout。顺便说一下,堆栈跟踪可以消除对问题原因的疑虑。

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

答案 1 :(得分: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

答案 2 :(得分:0)

不熟悉汇编,所以在黑暗中拍摄:你的字符串都是空终止的吗?

答案 3 :(得分:0)

你需要将你写入$ string的字符串空终止,而不是在一个字的顶部写三次。另外,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 );

}