2012-04-11 13 views
10

Si entiendo correctamente, DCPU-16 specification para 0x10c describe un espacio de direcciones de 16 bits donde cada desplazamiento trata una palabra de 16 bits, en lugar de un byte como en la mayoría de las otras arquitecturas de memoria. Esto tiene algunas consecuencias curiosas, p. Imagino que sizeof(char) y sizeof(short) devolverían 1.Portabilidad del código C para diferentes esquemas de direccionamiento de memoria

¿Es factible mantener el código C portátil entre estos esquemas de direcciones de memoria diferentes? ¿Cuáles serían los inconvenientes para tener en cuenta?

editar: quizás debería haber dado un ejemplo más específico. Digamos que tiene un código de red que trata con flujos de bytes. ¿Desechas la mitad de tu memoria al poner solo un byte en cada dirección para que el código permanezca igual, o generalizas todo con bitshifts para tratar con N bytes por desplazamiento?

edit2: Las respuestas parecen enfocarse en el tema del tamaño de los tipos de datos, lo cual no era el punto; ni siquiera debería haberlo mencionado. La pregunta es cómo lidiar con la pérdida de la capacidad de direccionar cualquier byte en la memoria con un puntero. ¿Es razonable esperar que el código sea agnóstico sobre esto?

+3

Siempre y cuando no hagas cosas como asumir que CHAR_BIT siempre es 8, entonces no hay un gran problema. – Flexo

+1

Sí, es factible. –

+0

Mientras siga el estándar C y no haga suposiciones sobre cosas que el estándar dice que son variables o dan como resultado un comportamiento o resultados no definidos o no especificados o definidos por la implementación, debería estar bien. –

Respuesta

9

Es totalmente factible. En términos generales, tipos de datos enteros básicos de C tienen tamaños que sostienen:

sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) 

Lo anterior no es exactamente lo que dice la especificación, pero está cerca.

Como lo señaló awoodland en un comentario, también esperarías que un compilador de C para DCPU-16 tenga CHAR_BIT == 16.

La bonificación por no suponer que el DCPU-16 tendría sizeof (char) == 2, es una falacia común.

+11

Se debe mencionar que 'sizeof (char)' es ** siempre ** 1. –

0

La igualdad va bien así:

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) 

El tipo short puede ser 1, y como cuestión de hecho, puede que incluso se va a querer el tipo int sea demasiado 1 realidad (no lo hice lea la especificación, pero supongo que el tipo de datos normal es de 16 bits). Esto es definido por el compilador.

Para mayor practicidad, el compilador puede querer configurar long a algo mayor que int, incluso si requiere que el compilador haga un trabajo extra (como implementar adiciones/multiplicaciones, etc. en el software).

Esto no es un problema de direccionamiento de memoria, sino más bien una cuestión de granularidad.

6

Cuando dice 'perder la capacidad de direccionar un byte', supongo que quiere decir 'bit-octet', en lugar de 'char'. El código portátil solo debe asumir CHAR_BIT >= 8. En la práctica, las arquitecturas que no tienen direccionamiento de bytes a menudo definen CHAR_BIT == 8, y permiten que el compilador genere instrucciones para acceder al byte.

En realidad estoy en desacuerdo con las respuestas que sugieren: CHAR_BIT == 16 como una buena opción. Prefiero: CHAR_BIT == 8, con sizeof(short) == 2. El compilador puede manejar el desplazamiento/enmascaramiento, al igual que para muchas arquitecturas RISC, para el acceso de bytes en este caso.

Imagino que Notch revisará y aclarará aún más la especificación DCPU-16; ya hay solicitudes para un mecanismo de interrupción y más instrucciones. Es un telón de fondo estético para un juego, por lo que dudo que haya una especificación ABI oficial pronto. Dicho esto, alguien estará trabajando en ello!

Editar:

considerar una variedad de char en C. El compilador paquetes de 2 bytes en cada 16 bits nativo word de memoria DCPU. Entonces, si accedemos, por ejemplo, al décimo elemento (índice 9), buscamos la palabra # [9/2] = 4 y extraemos el byte # [9% 2] = 1.

Dejemos que 'X' sea dirección inicial de la matriz, y 'I' el índice:

SET J, I 
SHR J, 1 ; J = I/2 
ADD J, X ; J holds word address 
SET A, [J] ; A holds word 
AND I, 0x1 ; I = I % 2 {0 or 1} 
MUL I, 8 ; I = {0 or 8} ; could use: SHL I, 3 
SHR A, I ; right shift by I bits for hi or lo byte. 

el registro A mantiene el 'bytes' - es un registro de 16 bits, por lo que la mitad superior puede ser ignorada. Alternativamente, la mitad superior puede poner a cero:

AND A, 0xff ; mask lo byte. 

Esto no está optimizado, pero transmite la idea.

+0

Entonces, ¿es posible que los compiladores de C emulen la memoria direccionable por bytes? ¡Interesante! –

+0

... pero ¿no reduciría eso a la mitad la memoria disponible si se atiene a un espacio de direcciones de 16 bits? ¿O el compilador agregaría bits a las direcciones, en este caso, un bit adicional para abordar el byte alto o bajo? –

+0

@WimCoenen - Edité la respuesta con un ejemplo –

0

Sí, es muy posible portar código C

en términos de datos de transferencias sería aconsejable ya sea empaquetar los bits (o utilizar una compresión) o enviar en bytes 16 bits

porque la CPU será casi en su totalidad comunicarse sólo con (juego) dispositivos internos que es probable que también sea todo de 16 bits esto no debería ser un problema real,

Por cierto estoy de acuerdo que CHAR_BIT debería ser 16 como (IIRC) cada carbón debe ser direccionable por lo que haciendo CHAR_BIT ==8 se REQUIERE sizeof(char*) ==2 que hará todo lo demás complicado

Cuestiones relacionadas