在64位机器上使用printf打印指针地址

时间:2013-09-26 04:12:08

标签: c assembly

我已经为printf编写了自己的代码。 我正在使用64位计算机。我正在尝试打印指针地址。由于某种原因,我只得到低32位地址。你能帮帮我,为什么我没有得到完整的地址?到目前为止我的发现。

Breakpoint 1, kprintf (fmt=0xffffffff00201687 "%p") at sys/main.c:249
249                                      write_string(0x1F,"0x");
(gdb) p /x addr
$1 = 0xffffffff002050f4

这是我的相应代码。

247                       case 'p':  addr = va_arg(arg_p, uint64_t); // Print Address     of the pointer
248                                  //addr = (uint64_t) v;
249                                  write_string(0x1F,"0x");
250                                  write_string(0x1F,convert(addr,16));
251                                  break;

奇怪的是我发现转换函数的参数是实际通过%edi 寄存器,这就是为什么我得到一个32位的值。但我想知道为什么没有通过%rdi寄存器。这是我的objdump / disassembly

 658 ffffffff00200a34:       48 89 44 24 08          mov    %rax,0x8(%rsp)
 659 ffffffff00200a39:       be 0a 00 00 00          mov    $0xa,%esi
 660 ffffffff00200a3e:       8b 39                   mov    (%rcx),%edi
 661 ffffffff00200a40:       e8 c3 01 00 00          callq  ffffffff00200c08 <convert>

这是我在转换函数中接收参数的方法。

 13 char *convert(uint64_t num, int base)
 14 {

有人可以告诉我这里的问题吗?

编辑:添加更多代码

int kprintf(char *fmt,...){
   char *p;
   uint64_t addr;
   int i; // integer argument
   char *s; // string argument
   va_list arg_p; // pointer to the variable argument list
   va_start(arg_p, fmt); 
   for(p=fmt; *p ; p++){
           if(*p != '%'){
                   write_char(0x1F,*p);
                   continue;
           }
           switch(*++p){
                  case 'p':  addr = va_arg(arg_p, uint64_t); // Print Address of the pointer
                             //addr = (uint64_t) v;
                             write_string(0x1F,"0x");
                             write_string(0x1F,convert(addr,16));
                             break;

           }

我的va_list

1 #define va_start(v,l) __builtin_va_start(v,l)
2 #define va_arg(v,l)   __builtin_va_arg(v,l)
3 #define va_end(v)     __builtin_va_end(v)
4 #define va_copy(d,s)  __builtin_va_copy(d,s)
5 typedef __builtin_va_list va_list;

我按照以下方式调用我的krpintf

kprintf("%p",(uint64_t)&i);

最后,我的转换功能是

 13 char *convert(uint64_t num, int base)
 14 {
 15 static char buf[65];
 16 char *ptr;
 17
 18 ptr=&buf[sizeof(buf)-1];
 19 *ptr='\0';
 20 do
 21 {
 22 *--ptr="0123456789abcdef"[num%base];
 23 num/=base;
 24 }while(num!=0);
 25 return(ptr);
 26 }

0 个答案:

没有答案