【问题标题】:read byte by byte from memory without system call or a library function in C从内存中逐字节读取,无需系统调用或 C 中的库函数
【发布时间】:2012-11-23 20:24:39
【问题描述】:

我想在不使用任何库函数的情况下将信息逐字节从一个内存位置移动到另一个位置。我使用在 qemu 中模拟的 16 位架构,这段代码是我正在编写的微小内核的一部分,所以我不能使用任何系统调用

// The struct i want to copy
struct procinfo info_tmp;
// here i put some stuff in my struct    
info_tmp.pid = tablaprocesos[indiceProceso].pid;
kstrcpy(info_tmp.nombre, tablaprocesos[indiceProceso].nombre);  
info_tmp.segmento = tablaprocesos[indiceProceso].memoria;
if(tablaprocesos[indiceProceso].estado==PROCESO_LISTO)
  info_tmp.estado = 0;
else if(tablaprocesos[indiceProceso].estado==PROCESO_RUN)
  info_tmp.estado = 1;
else if(tablaprocesos[indiceProceso].estado==BLOQ_TECLADO ||
tablaprocesos[indiceProceso].estado==PROCESO_SYSCALL)
  info_tmp.estado = 2;
else
  info_tmp.estado = 3; // Zombie
// Tiempo total = tiempoSYS + tiempoUSER
info_tmp.tiempo = tablaprocesos[indiceProceso].tiempoUSER +
  tablaprocesos[indiceProceso].tiempoSYS;    

// pointer to destination that i want to copy to
infoProc = (struct procinfo *)(((int)es << 16) + (0x0000ffff & ebx));
// now pointer to my source struct  
procinfo * origen = &info_tmp;         
int limit = sizeof(struct procinfo);
int i;
for(i=0;i<limit;i++){  
   //  I need here to read only one byte from my source pointer to a variable "byte"

   // macro written in ASM to copy one byte to a pointed location
   // it writes in another data segment of another process
   WRITE_POINTER_FAR(infoProc,byte);
   // next byte
   origen += 1; 
   infoProc += 1;
}

有没有直接的方法可以不用在 ASM 中编写小代码来手动完成?

注意:此代码是 16 位分段 OS 内核的一部分(每个进程一个 64KB 段),源结构在内核段中,我想将其复制到另一个进程段中的位置,它不能比如 *targetBytePointer = *sourceBytePointer。

【问题讨论】:

  • 为什么 *targetBytePointer = *sourceBytePointer;工作?我一定在你的要求中遗漏了一些东西......
  • 1) 风格:else if ... else if ...:考虑一个 swith 构造,这将消除很多视觉混乱。 2) origen + 0x1; 声明没有意义 3) 为什么十六进制常量为 1 ?
  • 它是一个 16 位分段 OS 内核(每个进程一个段),你看到的是在内核段中,我想将它复制到另一个进程段中的一个位置,它不能完成按照你的建议
  • wildplasser,由 origen + 0x1;我假装对指向我的源结构的指针求和一,这意味着指向我的源中的下一个字节(十六进制常量一无所获,只有一个)
  • Travis Griggs,此代码是 16 位分段 OS 内核(每个进程一个 64KB 段)的一部分,源结构位于内核段中,我想将其复制到另一个进程中的某个位置段,它不能像 *targetBytePointer = *sourceBytePointer.

标签: c memory assembly byte


【解决方案1】:

我终于写了一个小的 ASM 代码来手动完成。我必须这样做,因为正如我之前提到的,它是我在 qemu 中编写和模拟的 16 位内核的代码片段,它会进行内存分段(每个进程 64KB,总共 10 个进程)。我不能做*targetBytePointer = *sourceBytePointer,因为 targetPointer 在进程段中,而 sourcePointer 在内核段中,这就是为什么我有宏 WRITE_POINTER_FAR 的原因。基本上 WRITE_POINTER_FAR(写的是 ASM)将使用我已经创建的目标指针,结合调用进程在两个寄存器(ES:BX)中传递给我的内容,并且只会向该目标写入一个字节,这就是我需要只读的原因每次从我的源中获取一个字节。

char byte;
struct procinfo * origen = &info_tmp;  
for(i=0;i<limit;i++){
  asm( // leer un byte
    "mov %1,%%ebx   \n\t"
    "mov (%%ebx),%0  \n\t"
    :"=r"(byte)
    :"r"(origen)
  );
  WRITE_POINTER_FAR(infoProc,byte);
  origen += 1;
  infoProc += 1;
}

编辑:另一个简单的解决方案

char *byte;
struct procinfo * origen = &info_tmp;  
for(i=0;i<limit;i++){     
  byte = (char*)origen;
  WRITE_POINTER_FAR(infoProc,*byte);
  origen += 1;
  infoProc += 1;
}
// actualizar puntero de proceso
if(indiceProceso+1<=MAX_PROCESOS)
  indiceProceso++;
return 0;

【讨论】:

  • 你再做一次:origen + 0x1; infoProc + 0x1; 这些语句什么都不做!你想增加这两个指针吗? :使用origen += 1; infoproc +=1;(或origin++;等)
  • 您的 *byte 指针在循环的每次交互中都设置为原点的开头;最后的增量我们仍然没用。看我的回答。您还需要添加一些分号。
  • 我没有看到问题,因为我已经按照您的建议更改了增量:`origen += 1;信息处理 +=1; `
  • origen 和 infoproc 指针没有字符粒度。增加它们的意思是:将地址增加 sizeof (struct procinfo)
  • 在 16 位代码中使用 %ebx?呃……有人有点糊涂了。 EBX 是 32 位。
【解决方案2】:
// The struct i want to copy
struct procinfo info_tmp;
// here i put some stuff in my struct    
info_tmp.pid = tablaprocesos[indiceProceso].pid;
kstrcpy(info_tmp.nombre, tablaprocesos[indiceProceso].nombre);  
info_tmp.segmento = tablaprocesos[indiceProceso].memoria;

switch(tablaprocesos[indiceProceso].estado) {
case PROCESO_LISTO:
  info_tmp.estado = 0; break;
case PROCESO_RUN:
  info_tmp.estado = 1; break;
case BLOQ_TECLADO :
case PROCESO_SYSCALL:
  info_tmp.estado = 2; break;
default:
  info_tmp.estado = 3; // Zombie
        break;
        }
// Tiempo total = tiempoSYS + tiempoUSER
info_tmp.tiempo = tablaprocesos[indiceProceso].tiempoUSER +
  tablaprocesos[indiceProceso].tiempoSYS;

// pointer to destination that i want to copy to
infoProc = (struct procinfo *)(((int)es << 16) + (0x0000ffff & ebx));
char *dest = (char*) infoProc;
// now pointer to my source struct  
char * origen = (char*) &info_tmp;
int limit = sizeof(struct procinfo);
int i;
for(i=0;i<limit;i++){ 
   char byte;
   //  I need here to read only one byte from my source pointer to a variable "byte"

   // macro written in ASM to copy one byte to a pointed location
   // it writes in another data segment of another process
   byte = *origen;
   WRITE_POINTER_FAR(dest,byte);
   // next byte
   origen += 1;
   dest += 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多