2009-11-30 3 views
5

나는 그것은 C 라이브러리 호출하는 부분에서 세그먼트 오류가 발생하여 다음 코드조립 분할은 오류

#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 라이브러리와 관련하여 x64 코드를 컴파일하는 동안 놓친 내용이 있습니까? 모두 당신의 문자열이 종료 null 인 : 또는

감사

+2

그 movq의 – Managu

+1

감사 사이에 적절한 양에 의해 %의 RDI를 늘릴 수도 있습니다 모두, 나는 그 문제를 해결했다. 내가 /lib/ld-linux-x86-64.so.2를 수동으로 쓴 다음로드 된 주저 함수가 _start로 바뀌 었습니다. 동적 링크로 사용했습니다. 나쁜 영어로 죄송합니다. –

답변

0

하지 조립을 잘 알고, 그래서 어둠 속에서 촬영이 코드에 문제가 있습니까?

+0

.ascis는 자동으로 종료 null을 추가합니다. – querist

4

C 런타임 라이브러리의 초기화가 호출 되었습니까? stdout을 설정하려면 먼저 실행해야합니다. BTW, 스택 추적은 문제의 원인에 대한 의심을 제거합니다.

또한 % .0s 변환이 % .12s가있는 버퍼 오버플로를 방지하거나 버퍼 다음에 NUL 바이트를 넣지 마십시오.

0

한 단어 위에 세 번 쓰지 않고 $ buffer에 쓰는 문자열을 null로 종료해야합니다. 또한, wallyk가 맞습니다. CRT가 초기화되고 있습니까?

솔직히 C에서 C 라이브러리 함수를 호출하는이 프로그램을 작성하는 것이 훨씬 낫습니다. CPUID 코드를 __cdecl 함수 내부에 인라인 어셈블리로 작성하고 결과를 문자열 포인터에 쓰게 한 다음 그 함수를 C 프로그램에서 호출하십시오. 64 비트는 fprintf에 대한

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); 

} 
2

어셈블러 호출은 겉으로 변경, 그러니 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 
+0

movq 명령은'(% rdi)'를 증가시키지 않으므로, 뭔가를 놓치지 않으면'movq $ buffer, (% rdi)'는'movq $ output, % rdi'에 의해 덮어 쓰게 될 것입니다 나중에 라인. 나는 당신이하고있는 것을 볼 수 있지만, 어쨌든 몇 줄 후에'$ rsi'에'$ buffer'를'% rsi'에 복사하려고 할 때 왜'% rdi'를 사용해야합니까? – querist