1

ライブラリ関数を使用せずに、あるメモリ位置から別のメモリ位置に情報をバイト単位で移動したいと考えています。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.

4

2 に答える 2

1
// 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;
}
于 2012-12-05T23:14:53.957 に答える
0

最後に、手動で行うための小さな ASM コードを作成しました。前に述べたように、これは 16 ビット カーネルのコードの断片であり、qemu で記述およびエミュレートしており、メモリ セグメンテーション (プロセスごとに 64KB、合計 10 プロセス) を行うため、そうしなければなりませんでした。*targetBytePointer = *sourceBytePointertargetPointer がプロセス セグメントにあり、sourcePointer がカーネル セグメントにあるため、マクロ WRITE_POINTER_FAR を使用することはできません。基本的に WRITE_POINTER_FAR (書かれているのは ASM) は、呼び出し元のプロセスが 2 つのレジスタ (ES:BX) に渡したものを組み合わせて既に作成した宛先ポインターを使用し、その宛先に 1 バイトだけを書き込みます。そのため、読み取りのみが必要でした。毎回ソースから 1 バイト。

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;
于 2012-12-05T22:45:54.793 に答える