Em, bastante interesante lo que estas haciendo, dejame ver si encontre el problema.
BITS 16
start:
mov ax,0x07C0 ; Lo ponemos como 0
mov ds, ax
mov ax, text_string ; El cálculo debería ser DS * 0x10 + SI, lo que es lo mismo que
; 0x07C0 * 0x10 + SI, lo que es lo mismo que 0x7C00 + SI, que
; a su vez es lo mismo que el cálculo manual antes expuesto
mov si, ax ; La guardo en SI
Deberia ser:
BITS 16
start:
mov ax,0x7C00 ; AX = 31744 // 7C00h // &H7C00 // 0x7C00
mov ds, ax
add ax, text_string ; utilizamos ADD para sumar la dirección con el valor previo de AX.
mov si, ax ; Preservamos el valor en SI.
Ví que cambiaste 7C00h por por 0x07C0, No son lo mismo!
Y creo que podes achicarlo un poquito mas:
BITS 16
start:
mov si,0x7C00 ; SI = 31744 // 7C00h // &H7C00 // 0x7C00
add si, text_string
xor ds,ds
Saludos!