汇编分段错误

5
我在运行以下汇编代码时遇到了一个错误。
#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库的内容?或者代码本身存在问题?

谢谢。


2
在那些movq之间,您可能希望适当增加%rdi的数量。 - Managu
1
感谢大家,我解决了这个问题。 原来我加载了错误的库,在手动使用/lib/ld-linux-x86-64.so.2进行链接后正常运作,并将主函数替换为_start。 我使用了动态链接进行链接。 非常抱歉我的英文不好。 - user221106
4个回答

4
C运行时库的初始化是否被调用了?这必须先运行,才能设置stdout。另外,堆栈跟踪将消除对问题原因的怀疑。
此外,请使用%.12s防止%s转换溢出缓冲区,或在缓冲区后面放置一个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呢? - querist

0

你需要给 $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 );

}

0

不熟悉汇编语言,所以只是猜测:你的两个字符串都以空字符结尾了吗?


.asciz会自动添加终止的空字符。 - querist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接