64,643
社区成员
发帖
与我相关
我的任务
分享
NASM 是x86 的一个汇编器, 偶比较喜欢它的格式而已, 你也可以改成 Intel 格式或者是 AT&T 格式...
ARM 你还是搜下罢, 给你个简单的例子, VC 的嵌入汇编格式:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef backtrace_stack_size
#define backtrace_stack_size 0x40000
#endif
__declspec(naked) int __fastcall _x_backtrace( void* sym[] , int n )
{__asm {
push edi
push ebx
push ebp
xor eax , eax
test edx , edx
jle short backtrace_done ; if( n <= 0 ) return 0
mov ebx , [esp+12] ;
mov [ecx] , ebx ;
lea edi , [esp+backtrace_stack_size] ; end of stack
get_next_frame:
lea ecx , [ecx+4]
lea eax , [eax+1]
add edx , -1
jz short backtrace_done ;
cmp ebp , esp ; if( stack_frame < stack ) break
jb short backtrace_done
cmp ebp , edi ; if( stack_frame > stack + backtrace_stack_size ) break
ja short backtrace_done
mov ebx , [ebp+4]
or ebx , ebx
jz short backtrace_done
mov [ecx] , ebx
mov ebp , [ebp+0] ;
jmp short get_next_frame
backtrace_done:
pop ebp
pop ebx
pop edi
ret
}}
void show_backtrace_info()
{
void* callstack[32];
int n , i;
n = _x_backtrace( callstack , sizeof( callstack ) / sizeof( callstack[0] ) );
fprintf( stderr , "[INFO]backtrace return %d\n" , n );
for( i = 0; i < n; ++i )
{
fprintf( stderr , "[INFO]callstack %d : %p\n" , i , callstack[i] );
}
}
int main()
{
show_backtrace_info();
return 0;
}
%include "_x_std_macro.inl"
global _X_FASTCALL_SYMBOL( _x_peer_backtrace,8)
section .text
;
; ---- default stack size : 256K -----
;
%ifndef backtrace_stack_size
%define backtrace_stack_size 0x40000
%endif
_X_FUNC_ALIGN
_X_FASTCALL_SYMBOL( _x_peer_backtrace,8):
push edi
push ebx
push ebp
xor eax , eax
test edx , edx
jle short backtrace_done ; if( n <= 0 ) return 0
mov ebx , [esp+12] ;
mov [ecx] , ebx ;
lea edi , [esp+backtrace_stack_size] ; end of stack
get_next_frame:
lea ecx , [ecx+4]
lea eax , [eax+1]
add edx , -1
jz short backtrace_done ;
cmp ebp , esp ; if( stack_frame < stack ) break
jb short backtrace_done
cmp ebp , edi ; if( stack_frame > stack + backtrace_stack_size ) break
ja short backtrace_done
mov ebx , [ebp+4]
or ebx , ebx
jz short backtrace_done
mov [ecx] , ebx
mov ebp , [ebp+0] ;
jmp short get_next_frame
backtrace_done:
pop ebp
pop ebx
pop edi
ret
struct stackframe {
struct stackframe *fp;
void* sp;
void* lr;
};
#define BACKTRACESTACKSIZE (8*1024)
int _x_peer_backtrace ( void* syms[] , int size )
{
int i;
struct stackframe *tail = NULL;
void *sptr;
__asm__ __volatile__ (
"mov %[fptr] , fp\n\t"
"mov %[sptr] , sp\n\t"
: [fptr] "=r"(tail) , [sptr] "=r"(sptr) );
if( NULL == tail )
return 0;
for( i = 0; tail && i<size; )
{
if( (void*)tail < sptr ||
(void*)tail > (void*)( (unsigned char*)sptr + BACKTRACESTACKSIZE ) )
break;
syms[i++] = tail->lr;
tail = tail->fp;
if( NULL == tail )
break;
--tail ;
}
return i;
}