1 votos

La forma más sencilla de utilizar una CPU (Cómo aprender)

Sé un poco de programación, pero soy nuevo en cosas de bajo nivel, así que por favor perdonen la ingenuidad de esta pregunta. ¿Cuál sería la forma más directa de ejecutar una serie de comandos en una CPU para hacer una suma básica de 1+2=3 ? Por ejemplo, a un nivel relativamente alto, podría comprar un microcontrolador como un Arduino y escribir código C y compilarlo/ejecutarlo en el dispositivo, por ejemplo:

int main() {
    int a = 1;
    int b = 2;
    return a + b;
}   

¿Sería posible comprar algo como un Intel i7 Y, ¿ejecutar el ensamblador (binario compilado) en el chip sin un montón de periféricos? Supongo que mi pregunta es, dada una CPU, ¿qué es lo mínimo que se necesitaría para ejecutar instrucciones en ella y devolver/recibir algún tipo de salida? Sé que en "construye tu propio ordenador" está la CPU, la placa base, la RAM, el monitor, la fuente de alimentación, etc., pero ¿cuál sería la forma más básica de hacer esto?

El punto de esto es que estoy aprendiendo de montaje / instrucciones y me gustaría ir tan bajo nivel como puedo ir a entender cómo funcionan los componentes, sin entrar en la fabricación de la electrónica real (aparte de la configuración de las cosas / conectarlos).

4voto

Bartosz Radaczyński Puntos 7160

No quieres meterte con un intel, no. No es un buen comienzo. A menos que tal vez ejecute uno de los simuladores 8086/88, pero incluso entonces yo no empezaría allí.

En cuanto a aprender ensamblador, pdp11 (no es broma), msp430, arm thumb, arm, y algunos otros son buenos puntos de partida, construir una buena base entonces cada conjunto de instrucciones posterior es más fácil. Usted puede comenzar con las simulaciones y que no es un mal camino, hay simuladores pdp11 (simh), msp430 hay un núcleo abierto, armv2/3 núcleo abierto, además de un sinnúmero de mips y risc-v's que haría más tarde. Usted quiere algo apoyado por herramientas gnu por lo que todo lo anterior (sí hay un pdp-11 backend mantenido en binutils y gcc). msp430 y un sinnúmero de microcontroladores basados en el brazo están disponibles y los que sería el mejor lugar de hardware para empezar, que o un pi-cero (pero no una pi de tamaño completo ni beagle hueso negro no todavía). sí hay avr, etc, pero puede ser más difícil de usar dependiendo de lo que uno se obtiene.

Siendo realistas, hay muchas tarjetas mcu en el $10 to $ 20 que sería un buen punto de partida desde el punto de vista de los costes, algunos pueden requerir otro o unos pocos $2 - $ 20 tablas. Voy a elegir un camino primero.

st es una de las empresas líderes con mcus basados en cortex-m (arm) que funcionan en modo thumb, que es uno de los conjuntos de instrucciones de arm más sencillos. El conjunto de instrucciones con mayor compatibilidad en todo el mundo basado en el brazo.

Correr en linux te hará la vida mucho más fácil pero no es necesario, se pueden encontrar herramientas para Windows u OSX.

Un programa mínimo para sumar dos números para un cortex-m sería:

.thumb
.word 0x20001000
.word reset
.thumb_func
reset:
    mov r0,#1
    mov r1,#2
    add r2,r1,r0
    b .

eso es todo, el 100% del software

arm-linux-gnueabi-as flash.s -o flash.o
arm-linux-gnueabi-ld -Ttext=0x08000000 flash.o -o flash.elf
arm-linux-gnueabi-objcopy -O binary flash.elf flash.bin
arm-linux-gnueabi-objdump -d flash.elf > flash.list

El código en esta respuesta no importa entre arm-none-eabi- y arm-linux-gnueabi- construido herramientas gnu.

cat flash.list

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000
 8000004:   08000009

08000008 <reset>:
 8000008:   2001        movs    r0, #1
 800000a:   2102        movs    r1, #2
 800000c:   180a        adds    r2, r1, r0
 800000e:   e7fe        b.n 800000e <reset+0x6>

Estoy llevando a una placa / chip / familia en particular el núcleo en realidad busca la tabla de vectores en 0x00000000 pero esta marca se dirige a la flash de usuario en 0x08000000 luego lo refleja a 0x00000000 si el chip está configurado para arrancar desde la flash de usuario. La primera palabra va en el puntero de la pila y la segunda es la dirección del vector de reinicio orred con uno (una cosa pulgar legado, rodar con ella).

Y entonces puedes ver que un registro se carga con un 1, otro con un 2 y luego se suman y se almacenan en un tercero.

Estoy empezando con un NUCLEO-F446RE que actualmente está disponible en amazon, mouser, digikey, st, etc. Más barato de lugares que no sean amazon, pero entonces usted paga el envío. Hay placas nucleo de $10 que funcionan bien tambien. Algunas de las placas nucleo no enganchan el uart de la mcu de destino a través del extremo de depuración de la placa (otra mcu), por lo que querrás hacer tu investigación primero. Si usted consigue uno de estos tableros, entonces usted dont por ahora necesita comprar cualquier otro hardware esto es todo.

Una vez conectada, la placa se muestra como una unidad virtual y basta con copiar el archivo .bin para cargar el programa en la memoria flash.

cp flash.bin /media/user/NODE_F446RE/

Ahora el programa está cargado el procesador se reinicia y el programa se ejecuta.

Usando otra herramienta gratuita, openocd puedo conectarme al depurador de la mcu:

openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg 
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
adapter speed: 2000 kHz
adapter_nsrst_delay: 100
none separate
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : clock speed 1800 kHz
Info : STLINK v2 JTAG v36 API v2 SWIM v26 VID 0x0483 PID 0x374B
Info : using stlink api v2
Info : Target voltage: 3.266535
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints

en otra ventana telnet en el depurador openocd, detener el núcleo y volcar los registros

telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800000e msp: 0x20001000
> reg
===== arm v7m registers
(0) r0 (/32): 0x00000001
(1) r1 (/32): 0x00000002
(2) r2 (/32): 0x00000003
(3) r3 (/32): 0x00000000
(4) r4 (/32): 0x00000000

Puede ver que los tres registros tienen los valores que programamos.

Así como el puntero de pila cargado en la tabla de vectores

(13) sp (/32): 0x20001000

Si quiero hacer esto en C y hacerlo un poco más complicado, Ill seguir adelante y hacer un proyecto más completo. 100% del código:

flash.s

.cpu cortex-m0
.thumb
.thumb_func
.global _start
_start:
.word 0x20001000
.word reset
.thumb_func
reset:
    bl main
    b .

main.c

unsigned int fun ( unsigned int a, unsigned int b );
int main ( void )
{
    return(fun(1,2));
}

fun.c

unsigned int fun ( unsigned int a, unsigned int b )
{
    return(a+b);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text   : { *(.text*)   } > rom
    .rodata : { *(.rodata*) } > rom
    .bss    : { *(.bss*)    } > ram
}

construya

arm-linux-gnueabi-gcc -Wall -O2 -ffreestanding -mcpu=cortex-m0 -mthumb -c main.c -o main.o
arm-linux-gnueabi-gcc -Wall -O2 -ffreestanding -mcpu=cortex-m0 -mthumb -c fun.c -o fun.o
arm-linux-gnueabi-ld -nostdlib -nostartfiles -T flash.ld flash.o main.o fun.o -o main.elf
arm-linux-gnueabi-objdump -D main.elf > main.list
arm-linux-gnueabi-objcopy -O binary main.elf main.bin

Tu programa de ejemplo es código muerto tal y como está escrito si optimizado no generaría una instrucción add en su lugar sería:

main:
   mov r0,#3
   bx lr

hay otras soluciones pero ocultando las constantes de la optimización

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>
    ...

08000010 <main>:
 8000010:   b510        push    {r4, lr}
 8000012:   2102        movs    r1, #2
 8000014:   2001        movs    r0, #1
 8000016:   f000 f801   bl  800001c <fun>
 800001a:   bd10        pop {r4, pc}

0800001c <fun>:
 800001c:   1840        adds    r0, r0, r1
 800001e:   4770        bx  lr

y la suma ocurre. r0 obtiene el 1, r1 el 2, entonces la suma convierte a r0 en el 3. Así que copia y ejecuta

> reg
===== arm v7m registers
(0) r0 (/32): 0x00000003
(1) r1 (/32): 0x00000002
(2) r2 (/32): 0x00000000

Último ejemplo

añadir esto a flash.s

.globl dummy
.thumb_func
dummy:
    bx lr

y usando este main.c

void dummy ( unsigned int );
int main ( void )
{
    unsigned int ra;
    for(ra=0;;ra++) dummy(ra);
}

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000
 8000004:   08000009

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <dummy>:
 800000e:   4770        bx  lr

08000010 <main>:
 8000010:   b510        push    {r4, lr}
 8000012:   2400        movs    r4, #0
 8000014:   0020        movs    r0, r4
 8000016:   f7ff fffa   bl  800000e <dummy>
 800001a:   3401        adds    r4, #1
 800001c:   e7fa        b.n 8000014 <main+0x4>
 800001e:   46c0        nop         ; (mov r8, r8)

así que tanto r4 como r0 contendrán el valor de conteo, si paramos y arrancamos y paramos podemos ver esos conteos

> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800000e msp: 0x20000ff8
> reg r0
r0 (/32): 0x0088B275
> resume 
> halt
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800000e msp: 0x20000ff8
> reg r0
r0 (/32): 0x009B0F27
> reg r4
r4 (/32): 0x009B0F27
> 

A continuación, puede pasar a parpadear leds, conseguir el uart inicializado y así sucesivamente.

Aquí es donde entiendes que la programación baremetal es 99% lectura e investigación, menos del 1% de tu tiempo se gasta en la aplicación real. Se lee mucho y se escribe una cierta cantidad de código desechable para averiguar lo que realmente quería decir el manual. También te das cuenta de que la mayor parte del trabajo tiene que ver con los periféricos y no con la arquitectura/conjunto de instrucciones. Pasas más tiempo configurando los registros de los periféricos que configurando el procesador, si es que lo haces.

Así que hay un montón de placas nucleo que soportan esta cosa "mbed" lo que implica que usted puede hacer la copia de la cosa archivo bin. También las hay basadas en nxp, ya que las primeras mbeds estaban basadas en nxp. (nxp es otra empresa que vende chips basados en cortex-m). Si inviertes en una placa nucleo como la mencionada anteriormente el extremo de depuración de la placa se puede utilizar para depurar otros mcus basados en cortex-m incluso de otros vendedores, o por unos pocos dólares puedes conseguir un depurador basado en swd o un breakout ftdi genérico que soporte mpsse (adafruit tiene uno para $15). If you are willing to gamble on ebay you can get a usb uart board for a couple of bucks and an swd debugger for five bucks. Or spend around $ 15 por cada uno a través de amazon, adafruit o sparkfun, cosas que querrás en tu caja de herramientas.

Otro camino que también se basa brazo es la frambuesa pi cero y un programa simple en que es:

mov r0,#1
mov r1,#2
add r2,r1,r0
b .

sin tabla vectorial.

Disassembly of section .text:

00000000 <.text>:
   0:   e3a00001    mov r0, #1
   4:   e3a01002    mov r1, #2
   8:   e0812000    add r2, r1, r0
   c:   eafffffe    b   c <.text+0xc>

a continuación, copia el archivo .bin en una tarjeta sd y llámalo kernel.img. junto con bootcode.bin y start.elf que obtienes de los proyectos github de la gente de raspberry pi. inserta la tarjeta sd en la placa y enciéndela.

puedes hacer depuracion jtag usando openocd pero necesitaras hardware y no podras depurar el programa anterior. El chip esta centrado en la gpu el jtag expuesto es la gpu, para conectar con el depurador jtag de arm necesitas reconfigurar algunos pines gpio para exponer el jtag lo que significa algun codigo extra de arm que configura esos pines gpio, entonces el ftdi breakout correcto u otra placa y cuatro cables jumper para las señales basicas del jtag y puedes usar openocd para conectar con el procesador y pararlo y tal. Dado que se ejecuta desde ram, una vez detenido, entonces usted podría cargar un programa

load_image main.elf
resume 0x00000000

luego se detiene la carga se reanuda, se repite hasta que se cuelga algún periférico o se descifra el programa, necesitando ocasionalmente reiniciar para poner el chip en un estado conocido.

Los otros pis son mucho mas complicados, no querras ir con baremetal por mucho tiempo. Sin embargo, lo bueno de las Pi es que hay un excelente foro de baremetal con mucha gente que conoce a fondo el núcleo arm y los chips, además de código de ejemplo de cómo hacer varias cosas, incluida la magia que necesitarás si quieres incursionar en los núcleos armv7 o armv8 multinúcleo en esa plataforma.

Hay una placa basada en risc-v por $ 9 en amazon, que tiene un esquema de carga basado en flash falso similar risc-v es un poco más difícil de empezar que el brazo / pulgar. así que yo no empezaría aquí, y no recuerdo lo que la depuración si hay algo disponible en este tablero, por lo que un poco a ciegas objetivo para el parpadeo del led a continuación, más tarde uart, entonces usted puede comenzar a utilizar los de depuración.

Ciertamente puedes comprar placas arduino y deshacerte del arduino sandbox y escribir programas y cargarlos, y hacer cosas similares a las anteriores. Hay un simulador del conjunto de instrucciones avr que puedes usar. La naturaleza harvard-ish del conjunto de instrucciones y algunas otras cosas que yo no empezaría allí, migth ir allí más tarde después de algún otro conjunto instruciton.

msp430 es un buen punto de partida sencillo claramente inspirado en el pdp11/lsi11 que es uno de los mejores primeros conjuntos de instrucciones. Las placas solían costar unos pocos dólares, pero ahora probablemente cuesten más como $10 to $ 20 y puede al menos programar el chip y los leds parpadeantes por sólo el costo de la placa con el software adecuado. Si quieres hacer uart, etc es posible que necesite una placa uart usb por unos pocos a 15 dólares.

opencores tiene algunos núcleos que puedes simular con herramientas como verilator o icarus, pero puedes terminar gastando mucho tiempo en conseguir que todo funcione especialmente si no tienes experiencia con estas herramientas o estos lenguajes de hardware. Pero coge el núcleo amber arm2/3 o uno de los otros, averigua cómo alimentar el núcleo, y podrás tener una experiencia completa de ver el código ejecutarse en un núcleo, ver las instrucciones obtenidas, decodificadas, etc, etc... Una vez que desarrollas código para un chip en una simulación es difícil cuando llega el silicio porque ahora no tienes visibilidad de lo que está pasando. (Es cierto que el silicio funciona órdenes de magnitud más rápido).

Otro enfoque es escribir su propio simulador de conjunto de instrucciones. msp430 probablemente puede golpear a cabo en una larga tarde. pulgar mínimo tal vez un día completo. a continuación, aprender a dominar la cadena de herramientas (sólo tiene que utilizar gnu binutils y gcc) para crear binarios como se ha indicado anteriormente, a continuación, alimentar su sim estos programas y hacer / verlos correr. Escribiendo un simulador y/o desensamblador aprenderás los matices del conjunto de instrucciones mejor que algunos profesionales que han estado usando ese conjunto de instrucciones durante años, ya que muy pocos realmente profundizan en los matices. Usar una cadena de herramientas depurada idealmente significa que el código es bueno y las cosas que no siempre están bien documentadas como el direccionamiento pc-relativo o la bifurcación se generan en el código máquina y puedes averiguar cómo decodificarlo.

Al fin y al cabo, no te limites a una sola plataforma; el planteamiento anterior contiene sugerencias de enfoques que, con suerte, maximizarán tu éxito inicial, limitarán tu frustración y tu deseo de abandonar y no volver a intentarlo. Con algunas marcas en la columna de la victoria que impulsa la motivación para seguir adelante y moler a través de los fracasos para llegar a más victorias. x86 es un poco de una bestia, que sin duda puede trabajar su camino hasta ella, pero ¿por qué? No vas a arrancar uno desde cero, ciertamente puedes empezar desde donde algo como windows o linux arranca desde los medios e ir desde allí. Una caja x86 tiene más procesadores no x86 que procesadores x86, hay más procesadores arm en esa caja que x86s, y/o un puñado de otros, 8051s, z80s, etc. x86 se está limitando rápidamente a servidores y por ahora ARM's para todo lo demás (teléfonos y tablets y pronto portátiles). Es interesante ver cómo es y cómo funciona un CISC en toda regla, y personalmente yo empezaría con un emulador de 8088/86 y tendría una experiencia manejable y segura con altas probabilidades de éxito. Y luego leer sitios como stackoverflow y intel docs para ver cómo el actual conjunto de instrucciones evolucionado con el tiempo, así como los detalles sangrientos de todos los sistemas de protección, etc.

Te recomiendo encarecidamente que empieces este viaje con microcontroladores y/o simuladores/emuladores. Es barato, la gente sigue desarrollando a este nivel, si uno no funciona para ti o lo brickeas oh bueno, compra otro o compra uno diferente por otros 10 dólares. Dependiendo del camino que quieras tomar puedes usar herramientas gratuitas como kicad, y comprar algunas partes de mcu de $1, un pcb de unos pocos dolares, soldar el chip tu mismo y abrir incluso mas chips con los que jugar que no tienen placas de evaluacion baratas.


EDITAR

releyendo la quesiton, "ver" la salida que no sea la visibilidad depurador de arriba, para que nucleo bordo

flash.s

.cpu cortex-m0
.thumb

.thumb_func
.global _start
_start:
.word 0x20001000
.word reset

.thumb_func
reset:
    bl notmain
    b hang
.thumb_func
hang:   b .

.thumb_func
.globl dummy
dummy:
    bx lr

notmain.c

void dummy ( unsigned int );

#define RCCBASE         0x40023800
#define RCC_AHB1ENR (*((volatile unsigned int *) (RCCBASE+0x30) ))

#define GPIOABASE       0x40020000
#define GPIOA_MODER (*((volatile unsigned int *) (GPIOABASE+0x00) ))
#define GPIOA_BSRR  (*((volatile unsigned int *) (GPIOABASE+0x18) ))

//PA5

int notmain ( void )
{
    unsigned int ra;
    unsigned int rx;

    ra=RCC_AHB1ENR;
    ra|=1<<0; //enable GPIOA
    RCC_AHB1ENR=ra;

    ra=GPIOA_MODER;
    ra&=~(3<<(5<<1)); //PA5
    ra|= (1<<(5<<1)); //PA5
    GPIOA_MODER=ra;

    for(rx=0;;rx++)
    {
        GPIOA_BSRR=((1<<5)<< 0);
        for(ra=0;ra<800000;ra++) dummy(ra);
        GPIOA_BSRR=((1<<5)<<16);
        for(ra=0;ra<800000;ra++) dummy(ra);
    }
    return(0);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text   : { *(.text*)   } > rom
    .rodata : { *(.rodata*) } > rom
    .bss    : { *(.bss*)    } > ram
}

construya

arm-linux-gnueabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
arm-linux-gnueabi-gcc -Wall -O2 -ffreestanding -mcpu=cortex-m0 -mthumb -c notmain.c -o notmain.o
arm-linux-gnueabi-ld -nostdlib -nostartfiles -T flash.ld flash.o notmain.o -o notmain.elf
arm-linux-gnueabi-objdump -D notmain.elf > notmain.list
arm-linux-gnueabi-objcopy -O binary notmain.elf notmain.bin

cópialo y el led parpadeará.

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000
 8000004:   08000009

08000008 <reset>:
 8000008:   f000 f804   bl  8000014 <notmain>
 800000c:   e7ff        b.n 800000e <hang>

0800000e <hang>:
 800000e:   e7fe        b.n 800000e <hang>

08000010 <dummy>:
 8000010:   4770        bx  lr
    ...

08000014 <notmain>:
 8000014:   2101        movs    r1, #1
 8000016:   b5f0        push    {r4, r5, r6, r7, lr}
 8000018:   46c6        mov lr, r8
 800001a:   4a12        ldr r2, [pc, #72]   ; (8000064 <notmain+0x50>)
 800001c:   b500        push    {lr}
 800001e:   6813        ldr r3, [r2, #0]
 8000020:   2780        movs    r7, #128    ; 0x80
 8000022:   430b        orrs    r3, r1
 8000024:   4910        ldr r1, [pc, #64]   ; (8000068 <notmain+0x54>)
 8000026:   6013        str r3, [r2, #0]
 8000028:   680b        ldr r3, [r1, #0]
 800002a:   4a10        ldr r2, [pc, #64]   ; (800006c <notmain+0x58>)
 800002c:   4e10        ldr r6, [pc, #64]   ; (8000070 <notmain+0x5c>)
 800002e:   401a        ands    r2, r3
 8000030:   2380        movs    r3, #128    ; 0x80
 8000032:   00db        lsls    r3, r3, #3
 8000034:   4313        orrs    r3, r2
 8000036:   600b        str r3, [r1, #0]
 8000038:   2320        movs    r3, #32
 800003a:   4698        mov r8, r3
 800003c:   4d0d        ldr r5, [pc, #52]   ; (8000074 <notmain+0x60>)
 800003e:   03bf        lsls    r7, r7, #14
 8000040:   4643        mov r3, r8
 8000042:   2400        movs    r4, #0
 8000044:   6033        str r3, [r6, #0]
 8000046:   0020        movs    r0, r4
 8000048:   3401        adds    r4, #1
 800004a:   f7ff ffe1   bl  8000010 <dummy>
 800004e:   42ac        cmp r4, r5
 8000050:   d1f9        bne.n   8000046 <notmain+0x32>
 8000052:   2400        movs    r4, #0
 8000054:   6037        str r7, [r6, #0]
 8000056:   0020        movs    r0, r4
 8000058:   3401        adds    r4, #1
 800005a:   f7ff ffd9   bl  8000010 <dummy>
 800005e:   42ac        cmp r4, r5
 8000060:   d1f9        bne.n   8000056 <notmain+0x42>
 8000062:   e7ed        b.n 8000040 <notmain+0x2c>
 8000064:   40023830
 8000068:   40020000
 800006c:   fffff3ff
 8000070:   40020018
 8000074:   000c3500

3voto

Spehro Pefhany Puntos 90994

Parece que quieres trabajar con un microcontrolador. Puedes escribir código en lenguaje ensamblador fácilmente para un microcontrolador de 8 bits. Podrías utilizar una placa Arduino y AVR Studio y programarlo a través de la cabecera ICSP con una herramienta adecuada. O un PIC etc.

Es factible programar ARM e incluso chips más complejos en ensamblador, pero hay que hacer muchos ajustes tediosos y no sería agradable (a menudo utilizamos herramientas sólo para arrancar el código de configuración con chips más complejos).

Con un simple procesador de 8 bits, puede que sólo haya 5 o 10 instrucciones arcanas y algunas variables de configuración configuradas para que funcione.

1voto

laptop2d Puntos 331

Este es un buen recurso si estás aprendiendo el conjunto de instrucciones x86: Microprocesadores Intel enter image description here

Utilicé este libro para construir mi propio Ordenador con microprocesador 8088 Empecé con el procesador y la ROM y luego fui añadiendo RAM y periféricos (como E/S). Muy didáctico.

Dado que los conjuntos de instrucciones x86 se basan en el conjunto anterior, las instrucciones son en su mayoría las mismas (con adiciones a las instrucciones y la anchura del bus)

Si no quieres construir un ordenador, tal vez un Microcontrolador 8051 sería mejor.

1voto

mmuurr Puntos 115

Lo mejor es empezar con un simulador. Mira esto:

Simulador MARS MIPS

Puede utilizar este simulador para escribir código ensamblador que luego puede compilar y ejecutar.

Asistí a una clase de sistemas embebidos avanzados y utilizamos este simulador para escribir programas sencillos para un procesador MIPS. Si no recuerdo mal, utilizamos este libro para aprender sobre la arquitectura:

Libro MIPS

La ventaja de utilizar este libro y el simulador es que obtendrás una buena comprensión fundamental de lo que ocurre en una CPU.

Si realmente quieres aprender mucho, puedes utilizar un lenguaje de descripción de hardware para diseñar tu propio procesador MIPS. Hay cursos universitarios completos en YouTube que hacen precisamente eso. Luego podrías simular tu diseño y ver el funcionamiento interno de la CPU. Incluso podrías llegar a cargar tu HDL en una FPGA y conectar periféricos como botones y LEDs y hacer un ordenador que funcione.

1voto

Joe Kearney Puntos 425

¿Sería posible comprar algo como un Intel i7 y, ejecutar el ensamblador (binario compilado) en el chip sin un montón de montón de periféricos?

¡No! Pero podrías usar una CPU más simple que requiera muy pocos circuitos de apoyo.

Ya sé que en los "build-your-own-computers" está la CPU, Motherboard, RAM, monitor. fuente de alimentación, etc, pero ¿cuál sería la forma más bare-bones para hacer esto?

Como mínimo necesitas la propia CPU, una fuente de reloj, algo de "memoria" para guardar el código del programa y una salida para ver lo que ha hecho. El circuito más básico posible consiste en la CPU, un cristal u oscilador externo, puentes o interruptores en el bus de datos para generar un opcode, y tal vez LEDs en algunas líneas de señal para mostrar lo que la CPU está haciendo. He aquí un ejemplo:-

circuito de prueba de CPU Z80 mínimo absoluto

enter image description here

Pero esto sólo puede ejecutar una instrucción una y otra vez, bueno para probar el funcionamiento básico de la CPU, pero nada más.

Para ejecutar código más complejo necesitas un chip RAM o ROM paralelo, que puedes programar por separado y luego insertar en el circuito. El siguiente paso es añadir un decodificador de direcciones para poder tener tanto ROM como RAM, un programa "monitor" de código máquina en la ROM para una programación interactiva, y un chip de E/S serie para conectar a un "terminal" (tu PC), y entonces tendrás un ordenador completo de placa única.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X