x86 machine code, 162 bytes
PROG.COM Download and run it in MS-DOS emulator, DOSBox for example.
90 B3 B4 B4 02 90 90 B3 B2 B2 48 90 90 B3 CD CD 21 90 90 B3 B2 B2 65 90
90 B3 CD CD 21 90 90 B3 B2 B2 6C 90 90 B3 CD CD 21 90 90 B3 CD CD 21 90
90 B3 B2 B2 6F 90 90 B3 CD CD 21 90 90 B3 B2 B2 2C 90 90 B3 CD CD 21 90
90 B3 B2 B2 20 90 90 B3 CD CD 21 90 90 B3 B2 B2 77 90 90 B3 CD CD 21 90
90 B3 B2 B2 6F 90 90 B3 CD CD 21 90 90 B3 B2 B2 72 90 90 B3 CD CD 21 90
90 B3 B2 B2 6C 90 90 B3 CD CD 21 90 90 B3 B2 B2 64 90 90 B3 CD CD 21 90
90 B3 B2 B2 21 90 90 B3 CD CD 21 90 90 B3 CD CD 20 90
after removal MINI.COM Download
90 B4 02 90 B2 48 90 CD 21 90 B2 65 90 CD 21 90 B2 6C 90 CD 21 90 CD 21
90 B2 6F 90 CD 21 90 B2 2C 90 CD 21 90 B2 20 90 CD 21 90 B2 77 90 CD 21
90 B2 6F 90 CD 21 90 B2 72 90 CD 21 90 B2 6C 90 CD 21 90 B2 64 90 CD 21
90 B2 21 90 CD 21 90 CD 20
How to run?
Install DOSBox, for Ubuntu/Debian
sudo apt install dosbox
Run it
dosbox
In DOSBOX
mount c /home/user/path/to/your/directory
c:
PROG.COM
MINI.COM
How does it works?
Machine operation codes represents assembly language instructions.
In MS-DOS to print char you will set registers and make interrupt. AH register will be 0x02, DL register contains your char. Interrupt vector is 0x21.
mov ah,0x2 ;AH register to 0x2 (B4 02)
mov dl,0x48 ;DL register to "H" (B2 48)
int 0x21 ;0x21 interrupt (CD 21)
MS-DOS COM file tiny model is good choise, because it doesn't have any headers. It is limited by 64K, but in our case it doesn't matters.
To stop program use 0x20 interrupt
int 0x20 ;0x20 interrupt (CD 20)
Magic
If you want to execute 0xAB opcode command with one parameter 0xCD, you write
AB CD
In PROG.COM
90 B3 AB AB CD 90
nop ; No operation (90)
mov bl,0xb4 ; BL register to AB (B3 AB)
AB CD command (AB CD)
nop ; No operation (90)
In MINI.COM
90 AB CD
nop ; No operation (90)
AB CD command (AB CD)
It is equal machine codes, if you don't use BL register.
Generator
Convert text file with hex to hex binary
cat hex_file | xxd -r -p > exec.com
function byte2hex(byte){
var ret=byte.toString(16).toUpperCase();
return ret.length==1 ? "0"+ret : ret;
}
function str2hex(str){
var ret = [];
for(var i=0;i<str.length;i++){
ret.push(byte2hex(str.charCodeAt(i)));
}
return ret;
}
function genCode(hexArr){
var ret = [["B4","02"]];
for(var i=0;i<hexArr.length;i++){
if(hexArr[i]!=hexArr[i-1]){
ret.push(["B2",hexArr[i]]);
}
ret.push(["CD","21"]);
}
ret.push(["CD","20"]);
return ret;
}
function magicCode(str){
var ret=[""];
var code=genCode(str2hex(str));
for(var i=0;i<code.length;i++){
ret.push("90 B3 "+code[i][0]+" "+code[i][0]+" "+code[i][1]+" 90");
if(i%4==3){ret.push("\n");}
}
return ret.join(" ");
}
function magicCodeMinified(str){
var ret=[""];
var code=genCode(str2hex(str));
for(var i=0;i<code.length;i++){
ret.push("90 "+code[i][0]+" "+code[i][1]);
if(i%8==7){ret.push("\n");}
}
return ret.join(" ");
}
var str=prompt("string","Hello, world!");
var out="PROG.COM\n" + magicCode(str)+"\n\nMINI.COM\n"+magicCodeMinified(str);
document.write(out.replace("\n","<br>"));
alert(out);