2011-03-23 88 views
4

這是一個面試問題,我在一本面試書中遇到,後來在面試中遇到。爲特定地址分配一個值

的問題是

如何分配值(比如0)到地址(比如0x12345678)。

我所能爲這個問題的嘗試(採訪結束後很長一段時間後)

的地址是可以存儲在一個指針數,我們可以爲其賦值地址由一個指針,它的值是地址,如:

  int* p = 0x12345678; 
     *p = 0; 

然而,這是不可能用的存儲器管理的系統上,因爲PROGR我沒有特殊地址的特權。

根據我自己的經驗,這種操作唯一有效的時間是在沒有任何操作系統的8086芯片上的實驗,並且那時我使用的語言是彙編語言。

請幫助我正確,完善和完善我的答案。謝謝。

回答

-1

也許答案是沒有答案,因爲在有內存管理的系統中是不可能的。

在沒有內存管理的系統中,我會直接嘗試使用匯編代碼。

希望它可以幫助

+0

這些都是我的問題,其實都包括在內。我想知道,對於這樣的(開放)問題,我應該談些什麼。 – 2011-03-23 17:31:50

0

這種事情最肯定的,即使在內存管理系統是可能的,如果指針超出當前進程的可移動空間,它會錯,但是那正是應該發生的。如果沒有,價值就會被設置並且隨時隨地。除此之外,你對我來說似乎很好。

+0

那麼通過_possible_,你的意思是它可以被編譯但是運行時異常執行? – 2011-03-25 00:54:54

3

您的代碼是正確的,但如果操作系統將0x12345678定義爲只讀,則可能會在運行時崩潰。

雖然「常規」操作系統這樣做,但「較輕」的操作系統卻沒有。

你想寫一個內核空間黑客程序來做到這一點。

我解決它爲Linux,如果你想看看:


1)建立該模塊(例如。KO):

#include <linux/module.h> 
#include <linux/fs.h>  /* for file_operations */ 
#include <linux/uaccess.h> /* copy_from & copy_to */ 

char* g_value=0; 
size_t size =0; 

int driver_open(struct inode *inode, struct file *filp) 
{ 
    printk("open driver"); 
    return 0; 
} 

int driver_write(struct file*,   /*ignored*/ 
       const char __user *umem,/*source in user-space's address*/ 
       size_t size,   /*max size to be writen*/ 
       loff_t*)    /*offset - ignored*/ 
{ 
    unsigned long ret = 0; 

    g_value = (char*) kmalloc(size, GFP_KERNEL); 

    if (!g_value) 
    { 
     printk("ERROR:allocation failure\n"); 
     return -ENOMEM; 
    } 

    ret = copy_from_user(g_value, /*destination*/ 
         umem,  /*source*/ 
         size);  /*size*/ 

    if (ret<0) 
    { 
     printk("ERROR:copy failure\n"); 
     return -EACCES; 
    } 

    return g_size = size;; 
} 

int driver_read(struct file*,  /*ignored*/ 
       char __user *umem, /*destination in user-space's address*/ 
       size_t size,  /*max size to be read*/ 
       loff_t*)   /*offset - ignored*/ 
{ 

    /* don't use copy_to_user(umem, &value, size)!! 
     we want to do exectly what it is made to protect from */ 

    int i = ((g_size>size)?size:g_size)-1; /*MIN(g_size,size)-1*/ 
    for (; i>=0; --i) 
    { 
     umem[i]=g_value[i]; /*can be done more effectively, thats not the point*/ 
    } 

    return size; 
} 

int driver_close(struct inode *inode, struct file *filp) 
{ 
    if (g_value) 
     free(g_value); 
    g_value = 0; 
    printk("close driver"); 
    return 0; 
} 

/***interface***/ 

struct file_operations driver_ops = { 
    open: driver_open, 
    write: driver_write, 
    read: driver_read, 
    release: driver_close 
}; 

/***implementation***/ 

static int g_driver_fd = 0; 

static void driver_cleanup(void) 
{ 
    printk("ERROR:driver exit\n"); 
    unregister_chrdev(g_driver_fd, "driver"); 
} 

static int driver_init(void) 
{ 

    printk("driver init\n"); 
    g_driver_fd = register_chrdev(0,"ROM-bypass", &driver_ops); 
    if (g_driver_fd<0) 
    { 
     printk("ERROR:failed to register char driver\n"); 
     return -1; 
    } 
    return 0; 
} 

module_init(driver_init); 
module_exit(driver_cleanup); 

/***documentation***/ 

MODULE_DESCRIPTION("write on OS's \"read only\" segment"); 
MODULE_AUTHOR("Elkana Bronstein"); 
MODULE_LICENSE("GPL"); 

2)把它添加到內核模塊:

$insmod example.ko 

3)找到該模塊的 '主要' 在列表中:

$cat /proc/devices 

4)製作與相關聯的節點設備:

$mknod /dev/rom_bypass c <major> <minor> 

'c'表示字符d evice和「次要」可以是任何的0-255

5)使用的設備在你的代碼文件:

int main() 
{ 

    int fd; 
    int value = 0; 

    fd = open("/dev/rom_bypass",O_RDWR);  
    if (fd<0) 
    { 
     fprintf(stderr,"open failed"); 
     return -1; 
    } 

    /*write the desirable value into the device's buffer*/ 
    write(fd,&value,sizeof(value)); 
    /*read the device's buffer into the desirable object - without checking*/ 
    read(fd,0x12345678,sizeof(value)); 

    close(fd); 
} 
1

這是(幾乎)不可能知道哪個存儲器位置可寫至。

您可以讓操作系統通過使用malloc()函數爲您提供一個可用地址,然後使用free()釋放該位置。

另一種方法是使用堆棧內存。只需定義一個變量int * p = 0; & p會給你這個位置的地址。

如果您嘗試將值分配給不可用的位置,最終可能會出現分段錯誤錯誤。

希望這會有所幫助!

+0

哦,我剛剛看到日期。猜猜我遲了2年:P – user2438252 2013-06-04 10:21:40