48
Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga esta leyenda

Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Embed Size (px)

Citation preview

Page 1: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Introducción a la Arquitectura Intel x86

© M.C.C. Sergio Luis Castillo ValerioEsta presentación puede reproducirse libremente

siempre y cuando se mantenga esta leyenda

Page 2: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Arquitectura 80X86

CPU80X86

MemoriaRAM

Puertos E/S

Bus de Direcciones

Bus de Datos

Bus de Control

Page 3: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registros

• Registro: Conjunto de flip-flops capaz de almacenar, y en algunos casos modificar, información binaria.

• Dentro de todo CPU existe un conjunto de registros.

• Algunos tienen un uso específico, otros son de uso general (registros asimétricos).

• Los registros de uso general normalmente se utilizan para guardar datos y resultados intermedios.

Page 4: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registros

• Desde el punto de vista del programador, es muy importante conocer el conjunto de registros internos de un procesador y su uso, cuando se programa en bajo nivel.

• Esto se debe a que muchas de las instrucciones de lenguaje máquina suponen que los datos están en alguno de los registros o almacenan el resultado en alguno de los registros internos.

Page 5: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registros de los procesadores 80X86

• Registros de Uso General:– EAX: Acumulador– EBX: Base– ECX: Contador– EDX: Datos.– Estos registros pueden guardar datos de 32, 16 u 8 bits.

32 bits

16 bits

EAX

AX

AH AL

Page 6: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registros de los procesadores 80X86

– ESP: Stack Pointer (Apuntador de Pila)

– EBP: Base Pointer (Apuntador Base)– ESI: Source Index (Indice Fuente u Origen)– EDI: Destination Index (Indice Destino)– Estos registros pueden almacenar datos de 32 o 16 bits.

32 bits

16 bits

ESP

SP

Page 7: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registros de los procesadores 80X86

• Registros de Segmento– CS: Code Segment (Segmento de Código)– DS: Data Segment (Segmento de Datos)– SS: Stack Segment (Segmento de Pila)– ES: Extra Segment (Segmento Extra)– FS: Extra Segment (Segmento Extra)– GS: Extra Segment (Segmento Extra)

• Son registros de 16 bits.

• Se utilizan para generar las direcciones que el procesador envía por el bus de direcciones.

Page 8: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Registro de Banderas

• Conjunto de bits que nos dan información sobre el estado del procesador y sobre el resultado de la última operación efectuada.

• Es el único registro accesible a nivel de bits.

• Algunos de estos bits son:– CF: Carry flag - ZF: Zero flag– SF: Sign flag - OF: Overflow flag– IF: Interrupt flag - DF: Direction flag

. . . . . . . . OF DF IF SF ZF CF

Page 9: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmentación

• Técnica utilizada en los procesadores Intel 8088/8086 para generar direcciones de 20 bits usando registros de 16 bits.

– Para ilustrar esta técnica, suponga que se desea ubicar la posición de una persona a partir de un punto de referencia, pero utilizando solamente números de 2 dígitos decimales.

100 200 300 400 500 mts

Page 10: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmentación• Esto se puede realizar si se hace lo

siguiente:– Se divide la recta en bloques de 100 metros

cada uno.– Se utilizan dos números:

• Uno para indicar en cuál bloque está la persona

• Otro para especificar su posición dentro del bloque.

– Posición = Bloque:Posición

100 200 300 400 500 mts0:50 3:45

Page 11: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmentación

• Para obtener la ubicación real debe realizarse la siguiente operación:– Ubicación = Bloque*100 + Posición

• Posición1 = 0*100 + 50 = 50

• Posición2 = 3*100 + 45 = 345

100 200 300 400 500 mts0:50 3:45

Posición 1 Posición 2

Page 12: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmentación• En el caso de los procesadores 80X86, los

bloques se llaman SEGMENTOS y la posición se llama DESPLAZAMIENTO

• En modo real, cada una se describe con un número de 16 bits.

• Operando en modo real – Dirección Real = Segmento*16 + Desplazamiento.

• La Dirección Real ya es una cantidad de 20 bits.

• Esto significa que toda dirección tiene 2 partes: Un Segmento y un desplazamiento.

Page 13: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmentación en Modo Protegido

• Es importante recalcar que cuando los procesadores 80386 o posteriores operan en modo protegido, la segmentación funciona de manera muy diferente.

• Cada segmento puede ser de hasta 4 Gbytes.

• Maneja memoria virtual, lo que implica un esquema de paginación.

• Maneja también multitarea y un esquema de protección de memoria.

Page 14: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Conjunto de Instrucciones

• El Conjunto de instrucciones (Instruction Set) de un procesador está formado por aquellas instrucciones en lenguaje máquina que un procesador puede ejecutar.

• CISC vs. RISC– CISC: Complex Instruction Set Computer– RISC: Reduced Instruction Set Computer

• Las instrucciones normalmente se agrupan para describirlas.

Page 15: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Conjunto de Instrucciones

• Los grupos normalmente son:– Transferencia de datos– Aritmética entera binaria– Operaciones lógicas– Desplazamientos y rotaciones– Aritmética BCD– Gestión de cadenas– Control del sistema– Control de flujo del programa– Saltos condicionales

Page 16: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Tamaño de los Datos

• Byte

• Palabra (16 bits, 2 bytes)

• Palabra doble (32 bits, 4 bytes)

• Palabra cuadrúple (64 bits, 8 bytes)

• Direccionamiento a bytes

• Las palabras se leen en direcciones divisibles por su tamaño en bytes en forma little-endian.– Palabras dobles se leen en direciones divisibles por

4.

Page 17: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Tipos de Datos• General: Contenido binario arbitrario

• Entero: Valor binario simple, con signo o sin signo.

• BCD no empaquetado, 1 dígito por byte.

• BCD empaquetado, 2 dígitos por byte

• Apuntador cercano, dirección de 32 bits.

• Cadena de caracteres (secuencia de bytes ASCII)

• Punto flotante.

Page 18: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Grupos de Instrucciones

• Transferencia de datos– mov destino,origen - xchg dest,orig– in origen - out destino

• Aritmética entera binaria– add dest,orig - sub dest,orig– adc dest,orig - sbb dest,orig– mul orig - div orig– inc dest - dec dest

Page 19: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Grupos de Instrucciones

• Operaciones lógicas– not dest - and dest,orig– or dest,orig - xor dest,orig

• Desplazamientos y rotaciones– shl dest,# - shr dest,#– rol dest,# - ror dest,#

• Aritmética BCD– AAA :Ajuste ASCII suma – DAA :Ajuste decimal suma.– AAM :Ajuste ASCII muliplicación.– AAD :Ajuste ASCII división.

Page 20: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Grupos de Instrucciones• Gestión de cadenas

– rep: Repetir-lodsb:AL=byte{DS:SI}– stosb: {ES:SI} = AL– cmps: Compara {DS:SI} con {ES:DI}

• Control del sistema– int # - iret– cli: clear Interruption Flag– sti: set Interruption Flag– clc: clear carry flag– stc: set carry flag

Page 21: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Saltos condicionales

• Control de flujo del programa– jmp objetivo - test dest,orig– call procedimiento - ret– cmp dest,orig

• Saltos condicionales basados en:• Condiciones sobre indicadores• Relaciones aritméticas con signo• Relaciones aritméticas sin signo

Page 22: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Saltos condicionales• Condiciones sobre indicadores

– je/jne obj: jump if equal/not equal– jz/jnz obj: jump if zero/non zero– js/jns obj: jump if sign/no sign

• Relaciones aritméticas con signo– jg/jl obj: jump if greater/less– jge obj: jump if greater or equal– jle obj: jump if less or equal

Page 23: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Saltos condicionales• Relaciones aritméticas sin signo

– ja/jb obj: jump if above/below– jae/jbe obj: jump if above/below or equal

– jna/jnb obj: jump if not above/below

• Normalmente se utilizan después de una comparación:

Cmp dest,origjxx objetivo

(Donde xx: Condición de salto)

Nota: La instucción CMP resta el origen al destino y afecta banderas, noguarda el resultado ni altera los operandos.

Page 24: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Programación estructurada

• Es posible implementar parcialmente en bajo nivel las estructuras de control que propone la programación estructurada:

– If ... then– If ... then ... else– Repeat .... until– While ... do– For ... do

Page 25: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

If ... then

• Ilustraremos estas implementaciones con ejemplos:– En pseudocódigo:

– En ensamblador

cmp cx,ax ; if (cx > ax)jle fin_sidec cx ; then dec cx

fin_si:

If (cx > ax)then dec cx

Page 26: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

If ... then ... else

• Pseudocódigo:

• Ensamblador:

If (bx < ax) then dec ax else dec bx

cmp bx,ax ; If (bx < ax)jge else1dec ax ; then dec axjmp fin_si1

else1: dec bx ; else dec bxfin_si1:

Page 27: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Repeat ... until

• Pseudocódigo:

• Ensamblador:

Repeat: inc cx add ax,cxuntil (cx > 100)

Repite1:inc cxadd ax,cx

cmp cx,100 ; until (cx > 100)jle Repite1

Page 28: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

While ... do

• Pseudocódigo:

• Ensamblador:

While (bx<200) doinc bxadd ax,bx

end_while

while1: cmp bx,200 ; While (bx<200)jge fin_while1 inc bx add ax,cxjmp while1 ; end_while

fin_while1:

Page 29: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

For ... do

• Una implementación utiliza la instrucción loop

• Sintaxis loop:– loop objetivo

• Semántica:

• loop utiliza CX forzosamente

Si (CX 0) Dec CX Salta a objetivoSino Siguiente instrucción

Page 30: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

For ... do• Pseudocódigo:

• Ensamblador:

For (cx=1 hasta 20) do add ax,bx inc bxend_for

mov cx,20do1:

add ax,bxinc bxloop do1

Nota: Dentro de la imlementación del for ...do no es aconsejable utilizar CX cuando se implementa con loop.

Page 31: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Partes de un programa

• Todo programa de bajo nivel se compone de tres segmentos (secciones en modo protegido):– Datos (opcional): Contiene la definición y los

valores iniciales de las variables que utiliza nuestro programa.

– Pila (opcional): Reserva memoria para la pila (stack)

– Código: Contiene las instrucciones del programa. El segmento de código se subdivide en procedimientos. Debe haber por lo menos un procedimiento principal.

Page 32: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Definición de segmentos

• Los segmentos se definen con la directiva segment.

• Sintáxis:– segment nombre tipo

• Donde nombre es el nombre del segmento. Este nombre es definido por el programador.

• Y tipo puede ser: data, stack o code.

• Por ejemplo:– segment variables data

Page 33: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Definición de segmentos

• En nuestros programas definiremos los segmentos en el orden siguiente:– segment pila stack– segment datos data– segment programa code

• Cada segmento termina donde inicia el siguiente.

• La etiqueta ..start: define el procedimiento principal dentro del segmento de código.

Page 34: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Programa ejemplo

• Programa que suma los primeros 30 enteros.

• Pseudocódigo:Suma = 0i = 1Mientras (i 30) haz suma=suma+i i = i+1fin_mientrasfin.

Page 35: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Programa ejemplo• En ensamblador:

; AX = Suma, BX = isegment pila stack ; Define segmento de pilaresb 256 ; Reserva 256 bytessegment programa code ; Define segmento de código..start: mov ax,0 ; Suma=0

mov bx,1 ; i = 1mientras1: cmp bx,30 ; Mientras (bx 30) haz

jg fin_mientras1add ax,bx ; suma=suma+iinc bx ; i = i + 1jmp mientras1

fin_mientras1:mov ax,4c00h ; fin.int 21h

Page 36: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Ejercicio 1• Implementa el siguiente pseudocódigo en

ensamblador:

x=0y=1z=0Repite: z = x + y x = y y = zHasta (z > 1000)

Page 37: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Segmento de datos

• Cuando se programa en bajo nivel en la PC en modo real, nos enfrentamos con algunas características del MS-DOS.

• Una de ellas es el PSP: Prefix Segment Program.

• Cuando el MS-DOS carga un ejecutable de tipo EXE, carga a memoria los segmentos de pila, datos y código.

• Inicializa SS y CS para que apunten a sus respectivos segmentos.

Page 38: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

PSP• Crea el PSP, que es un bloque de 256 bytes

que contiene datos e instrucciones que el SO utiliza para retomar el control del sistema cuando nuestro programa termine su ejecución.

• Inicializa DS para que apunte al PSP, no a nuestro segmento de datos.

• Por tanto, siempre que se utiliza un segmento de datos es necesario inicializar DS a nuestro segmento de datos.

Page 39: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Inicialización de DS

• Para esto, cuando utilicemos un segmento de datos siempre ejecutaremos las siguientes instrucciones:– MOV AX, Nombre_segmento_datos

– MOV DS,AX

• Esto hace que DS apunte a nuestro segmento de datos y que podamos accesar los datos que definamos en nuestro programa.

Page 40: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Formato de instrucción• Los procesadores x86 de Intel son del tipo

CISC (Complex Instruction Set Computer).

• Tienen instrucciones de diferentes tamaños.

• Varios modos de direccionamiento.

• Instrucciones con varias posibilidades en lenguaje máquina.

Page 41: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Formato de instrucción

• Código Operación{d,v,s,w}:•Si d=1, “a”, si d=0 “de”;

•Si w=1, instrucción de una palabra, si w=0, instrucción de un byte.

•Si s:w=01, operando formado por dato inmediato de 16 bits.

•Si s:w=11, operando de 16 bits formado por un dato inmediato de 1 byte con extensión de signo.

•Si v=0, “conteo”=1, si v=1, “conteo” en CL.

Código Op. Modo Byte bajo datoByte alto dato

Page 42: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Formato de instrucción

• Modo: mod[reg]r/m, donde “mod”:

Código Op. Modo Byte bajo datoByte alto dato

mod Desplazamiento------------------------------------------------------------------00 DISP=0 (Desplazaminto ausente)01 DISP= Desplazamiento bajo de 16 bits con

signo. Desplazamiento alto ausente.10 DISP=Desplazamiento Alto:Desplazamiento

Bajo11 r/m se trata como un campo “reg”

Page 43: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Formato de instrucción

• Modo: mod[reg]r/m, donde “[reg]”:

Código Op. Modo Byte bajo datoByte alto dato

16 bits (w = 1) 8 bits (w=0) Segmento------------------------------------------------------------------------000 AX 000 AL 00 ES001 CX 001 CL 01 CS010 DX 010 DL 10 SS011 BX 011 BL 11 DS100 SP 100 AH101 BP 101 CH110 SI 110 DH111 DI 111 BH

Page 44: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Formato de instrucción

• Modo: Modo: mod[reg]r/m, donde “r/m”:

Código Op. Modo Byte bajo datoByte alto dato

r/m Dirección de los operandos-------------------------------------------------------------000 BX + SI + Desplazamiento001 BX + DI + Desplazamiento010 BP + SI + Desplazamiento011 BP + DI + Desplazamiento100 SI + Desplazamiento101 DI + Desplazamiento110 BP + Desplazamiento*111 BX + Desplazamiento

Page 45: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Ejemplo

• Instrucción mov (Mover)

-Registro/Memoria a/de registro: 1000 10dw + mod reg r/m-Inmediato a registro/memoria: 1100 011w + mod 000 r/m +

[byte bajo dato] + [byte alto dato, si w=1]-Inmediato a registro: 1011 w reg +[byte bajo dato] +

[byte alto dato, si w=1]-Memoria a Acumulador: 1010 000w + [byte bajo dirección] +

[byte alto dirección]-Acumulador a Memoria: 1010 001w + [byte bajo dirección] +

[byte alto dirección]-Registro/Memoria a Registro de Segmentación: 1000 1110 + mod 0 reg r/m-Registro de Segmentación a registro/memoria: 1000 1100 + mod 0 reg r/m

Page 46: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Ejemplo

• Instrucción mov ax,1234h• 2 Posibilidades:

– Inmediato a registro/memoria– Inmediato a registro

-Inmediato a registro/memoria:1100 011w + mod 000 r/m + [byte bajo dato] + [byte alto dato, si

w=1]

-Inmediato a registro:1011 w reg +[byte bajo dato] + [byte alto dato, si w=1]

Page 47: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Ejemplo

• Instrucción mov ax,1234h• Inmediato a registro/memoria:

1100 011(w=1)+(mod=11)000 (r/m=000)+ 34h + 12h=1100 0111 1100 0000 0011 0100 0001 0010=C7C03412h

Page 48: Introducción a la Arquitectura Intel x86 © M.C.C. Sergio Luis Castillo Valerio Esta presentación puede reproducirse libremente siempre y cuando se mantenga

Ejemplo

• Instrucción mov ax,1234h• Inmediato a registro:•1011 w reg +[byte bajo dato] + [byte alto dato, si w=1]

1011 (W=1)(reg=000) + 34h + 12h=1011 1000 0011 0100 0001 0010=B83412h