Assembly 装配分段故障

Assembly 装配分段故障,assembly,64-bit,libc,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

我在运行以下程序集代码时遇到错误

#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库的部分遇到了分段错误:callprintf 它在x86_64模式下运行。 在编译关于c库的x64代码时,我遗漏了什么?还是代码有问题


谢谢你对汇编不熟悉,所以我想问一下:你的两个字符串都以null结尾了吗?

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


另外,请防止%s转换使缓冲区溢出%.12s,或者在缓冲区后加一个NUL字节。

您需要使用null终止写入$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 );

}

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谢谢大家,我解决了这个问题。我用/lib/ld-linux-x86-64.so.2手动加载了一个错误的lib,然后用_start替换了主函数。我把它称为动态链接。很抱歉英文不好。
。asciz
会自动添加终止null。您的movq指令不会增加
(%rdi)
,因此除非我遗漏了什么,
movq$buffer,(%rdi)
只会在几行之后被
movq$output,%rdi
覆盖。我可以看到您在做什么,但是,当您稍后要将
$buffer
复制到
%rsi
几行时,为什么要使用
%rdi