什么是机器可读代码的语言?

时间:2016-05-12 10:00:45

标签: programming-languages exe vm-implementation machine-code

基本上,我所问的是计算机理解的语言是什么...... 我看过这篇文章解释了一点https://www.quora.com/How-are-exe-files-created-And-what-programming-language-are-used-in-creating-them,但它只是将它称为机器可读代码"。

我想知道编译时所有编程语言的转换。 是否可以编码知道"机器语言"不使用编译器?

它说它转换为"操作系统"或者"执行引擎(虚拟机)"但就是这样,我可以拿记事本只是写在那里,保存为.exe,它会按照它说的做什么?

如果你不能在没有.exe的情况下创建.exe,那么你是如何做到的?

比如,我可以创建一个独立的Windows应用程序而不需要像Visual Studio / Visual Basic这样的程序吗?

3 个答案:

答案 0 :(得分:2)

计算机执行机器代码。这取决于它的CPU。这就是您需要为特殊CPU类(例如i386,SPARC,...)编译软件的原因。因为他们理解不同的机器代码,或者它们的构建方式非常不同(例如RISC与CISC)。

在最高级别的程序代码和最低级别的机器代码之间可以存在多个层(例如汇编程序,对象代码......)。分层(隐藏下面层中的复杂性)是技术中最重要的概念之一。

基本上我们在编译器和解释器之间有所区别。编译器将高级代码(从人类)转换为低级代码(例如,机器代码)。解释器是一个运行程序,它将其输入作为命令。因此它会读取代码并按要求执行操作。

通常,解释器在平台上速度较慢但更独立(如果您在多个平台上拥有解释器程序)。 编译后的程序要快得多,但每个CPU都需要特殊。

EXE是一种机器代码格式。关于操作系统有几种不同。

我已经提到了汇编程序。它有点高于机器代码,因此对人类可读。在反汇编中,您需要一个程序(机器代码二进制文件)并将其转换为汇编程序。 机器代码和汇编程序是一个非常直接的映射。因此汇编程序中的1行将生成 - 比方说 - 机器代码中的1到5行。 高级语言(例如C ++)中的1行将在机器代码中产生更多行。 因此,在反汇编中,您尝试了解该程序,并可以将该信息用于进一步的需求(例如,如何解锁代码,破解,......)。

答案 1 :(得分:1)

首先,链接引用对于堆栈溢出是一件坏事,它可能会消失并破坏整个问题,使它成为我们必须丢弃的东西。

其次,引用显然是关于JAVA和JVM,并且极其误导,如果你不知道这些东西,这是一篇非常糟糕的文章。

作为一名程序员,我假设你明白,如果你给100名程序员一个编程任务,你最终会得到1到100种不同的解决方案。

硬件没有什么不同,给100个芯片设计师提供相同的设计任务,你可以得到1到100种不同的设计。硬件/电路板设计师,同样的交易。如果你告诉芯片设计师发明他们自己的指令集并设计一个处理器,它将倾向于100种不同的设计。如果你给它们指令集(机器代码规范),你仍然会得到1到100种不同的设计。

如果它是CISC或CISC,你最终可能会使用微编码,使用RISC你也可以,但这就是RISC不需要/想要微码的想法。

所有编程语言都太模糊了。同时,它们通常转换为某种较低级别的语言,并最终转换为可解析的内容。我们必须对答案含糊不清,因为我可以对此做出的每一个陈述都有例外。但是C / C ++通常被编译成特定目标的汇编语言,编译器要么被告知目标,要么经常是你运行它的那个,一个"交叉编译器"用于编译不同的目标。我不想继续使用通常的,大多数和其他模糊的术语......然后汇编程序将汇编语言转换为大多数机器代码,但如果它是一个对象,那么链接器就会留下一些东西来填写并最终确定。但即使是.exe或其他类似的foramats(coff,elf等),大部分文件都是程序,机器代码和数据,但是一些文件告诉操作系统如何加载该程序并启动它。你必须查找每个"二进制文件"文件格式类型,以了解它们如何执行此操作。然后在某些情况下,它可能仍然依赖于操作系统。

绝对没有理由不能直接或在您选择的任何路径中生成这些可执行文件。您可以使用十六进制编辑器(记事本不是其中之一)并开始输入文件的字节,.exe标题,机器代码,数据,整个事物。你当然可以用某种语言编写一个程序来编译并运行它,该程序可以直接创建另一个程序,而不是使用编译器只写出字节。

JAVA,早期的Pascal,Python,BASIC就此而言。这些不一定(尽管Pascal最近这样做)直接编译成"机器代码"对于您正在运行的处理器。按设计。 JAVA和Python希望在任何地方运行,独立于操作系统。他们有自己的机器代码,他们的编译器将源代码编译成机器代码,而不是目标处理器的机器代码,正在运行的机器代码,而是他们发明的通用处理器。然后你有一个JVM JAVA虚拟机,它是一个程序,可能不是用JAVA编写的,它依赖于操作系统并读取那个java机器代码的字节并像处理器那样执行它。同样适用于python,而在早期则同样适用于pascal。 BASIC,传统上你在运行时读取BASIC代码并解析并运行它。授予所有这些可能有一个人编写的工具链(或者只是其中一些gcc),而不是编译到langauge特定目标,而是可以编译成运行的处理器的机器代码,通常是设计不但是,有时候可以做到。

处理器本身并没有那么大的不同,只是读取机器代码的逻辑,解析出来的位并完成比特所说的事情。就像JVM为JAVA做的那样,但在硬件上要快得多。有时,更可能使用CISC(x86),你有微码,还有另一个指令集,就像JVM一样,它可能借助于硬件/逻辑来获取机器代码,并且在微编码软件中打破并执行它。我们通常不会看到那个微代码,因为你需要100名设计师,你得到100个结果,他们不想携带同一个微代码的每一代处理器,x86就是一个完美的例子,因为英特尔有两个或更多的设计中心做自己的事情,每一个或每三个芯片设计来自其中一个设计中心,所以我们继续在这些设计中心的偏好之间。或者至少他们曾经这样做不知道他们现在做了什么。

是的,你绝对可以在没有visual studio / visual basic的情况下编写一个windows程序。您可以使用十六进制编辑器并只输入字节,您可以使用汇编语言编写并使用汇编程序(和依赖于链接器)汇编它,这些汇编程序不是基于任何视觉的(例如,使用gnu binutils)。

如其他答案和评论中所述,或不。之前有任何这些工具"编译" "组装"是一个人写下了他们想要做的事情(可能是在流程图中),然后用某种形式的汇编语言再次写下来,这是人类可读的东西,然后是旁边那个或者从新页面开始编写机器代码。然后翻转开关或以其他方式将该机器代码输入处理器并启动它。使用该方法,您最终可以编写汇编程序,然后现在您有了汇编程序,您可以在汇编程序中再次编写该汇编程序,而不是手写的机器代码。现在您有了汇编程序,您可以创建语言并在汇编程序中实现它们,然后您可以使用相同的语言重新编写它们并使用该语言编译它们。并使用该语言制作其他语言。并且交叉编译langauges或汇编,对于你发明但没有工具但不想手写机器代码的其他平台。重复这几十年,我们在这里。甚至逻辑也是使用编程语言verlog和/或vhdl设计的,这些语言显然受到C和ADA等语言的影响。

我接受这个功能,但功能和程序有什么区别?让你思考一下。

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

我编译它。编译器生成汇编语言作为其输出

    .arch armv5t
    .fpu softvfp
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 2
    .eabi_attribute 30, 2
    .eabi_attribute 34, 0
    .eabi_attribute 18, 4
    .arm
    .syntax divided
    .file   "so.c"
    .text
    .align  2
    .global fun
    .type   fun, %function
fun:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 0, uses_anonymous_args = 0
    @ link register save eliminated.
    add r0, r0, r1
    bx  lr
    .size   fun, .-fun
    .ident  "GCC: (Ubuntu 5.2.1-22ubuntu1) 5.2.1 20151010"
    .section    .note.GNU-stack,"",%progbits
然后我将它组装成一个对象。一个hexdump:

0000000 457f 464c 0101 0001 0000 0000 0000 0000
0000010 0001 0028 0001 0000 0000 0000 0000 0000
0000020 019c 0000 0000 0500 0034 0000 0000 0028
0000030 000a 0007 0001 e080 ff1e e12f 4700 4343
0000040 203a 5528 7562 746e 2075 2e35 2e32 2d31
0000050 3232 6275 6e75 7574 2931 3520 322e 312e
0000060 3220 3130 3135 3130 0030 2941 0000 6100
0000070 6165 6962 0100 001f 0000 3505 0054 0306
0000080 0108 0109 0412 0114 0115 0317 0118 0119
0000090 021a 021e 2e00 7973 746d 6261 2e00 7473
00000a0 7472 6261 2e00 6873 7473 7472 6261 2e00
00000b0 6574 7478 2e00 6164 6174 2e00 7362 0073
00000c0 632e 6d6f 656d 746e 2e00 6f6e 6574 472e
00000d0 554e 732d 6174 6b63 2e00 5241 2e4d 7461
00000e0 7274 6269 7475 7365 0000 0000 0000 0000
00000f0 0000 0000 0000 0000 0000 0000 0001 0000
0000100 0000 0000 0000 0000 0004 fff1 0000 0000
0000110 0000 0000 0000 0000 0003 0001 0000 0000
0000120 0000 0000 0000 0000 0003 0002 0000 0000
0000130 0000 0000 0000 0000 0003 0003 0006 0000
0000140 0000 0000 0000 0000 0000 0001 0000 0000
0000150 0000 0000 0000 0000 0003 0005 0000 0000
0000160 0000 0000 0000 0000 0003 0004 0000 0000
0000170 0000 0000 0000 0000 0003 0006 0009 0000
0000180 0000 0000 0008 0000 0012 0001 7300 2e6f
0000190 0063 6124 6600 6e75 0000 0000 0000 0000
00001a0 0000 0000 0000 0000 0000 0000 0000 0000
*
00001c0 0000 0000 001b 0000 0001 0000 0006 0000
00001d0 0000 0000 0034 0000 0008 0000 0000 0000
00001e0 0000 0000 0004 0000 0000 0000 0021 0000
00001f0 0001 0000 0003 0000 0000 0000 003c 0000
0000200 0000 0000 0000 0000 0000 0000 0001 0000
0000210 0000 0000 0027 0000 0008 0000 0003 0000
0000220 0000 0000 003c 0000 0000 0000 0000 0000
0000230 0000 0000 0001 0000 0000 0000 002c 0000
0000240 0001 0000 0030 0000 0000 0000 003c 0000
0000250 002e 0000 0000 0000 0000 0000 0001 0000
0000260 0001 0000 0035 0000 0001 0000 0000 0000
0000270 0000 0000 006a 0000 0000 0000 0000 0000
0000280 0000 0000 0001 0000 0000 0000 0045 0000
0000290 0003 7000 0000 0000 0000 0000 006a 0000
00002a0 002a 0000 0000 0000 0000 0000 0001 0000
00002b0 0000 0000 0011 0000 0003 0000 0000 0000
00002c0 0000 0000 0094 0000 0055 0000 0000 0000
00002d0 0000 0000 0001 0000 0000 0000 0001 0000
00002e0 0002 0000 0000 0000 0000 0000 00ec 0000
00002f0 00a0 0000 0009 0000 0009 0000 0004 0000
0000300 0010 0000 0009 0000 0003 0000 0000 0000
0000310 0000 0000 018c 0000 000d 0000 0000 0000
0000320 0000 0000 0001 0000 0000 0000          
000032c

不一定适用于此程序,但通常更容易通过反汇编对象而不是详细程序集来查看编译器生成的内容。

Disassembly of section .text:

00000000 <fun>:
   0:   e0800001    add r0, r0, r1
   4:   e12fff1e    bx  lr

碰巧有我们的机器代码,所以我们可以输入这些字节。如上所述,这不是一个完整的程序,因为它需要一个特定于操作系统的进入和退出。

我可以在这个处理器上运行这个代码我选择了裸机,并且可以用这个引导程序包装它:

.globl _start
_start:
   mov sp,#0x8000
   bl fun
   b .

汇编和链接,我得到了这个例子

Disassembly of section .text:

00000000 <_start>:
   0:   e3a0d902    mov sp, #32768  ; 0x8000
   4:   eb000000    bl  c <fun>
   8:   eafffffe    b   8 <_start+0x8>

0000000c <fun>:
   c:   e0800001    add r0, r0, r1
  10:   e12fff1e    bx  lr

我可以将其转换为可以加载到ram或flash中的二进制图像,具体取决于该处理器并运行

0000000 d902 e3a0 0000 eb00 fffe eaff 0001 e080
0000010 ff1e e12f                              
0000014

不使用basic,不使用visual studio,不运行windows,我可以编写这个程序

#include <stdio.h>

static const unsigned int fun[]=
{
0xe3a0d902,
0xeb000000,
0xeafffffe,
0xe0800001,
0xe12fff1e,
};

int main ( void )
{
    FILE *fp;

    fp=fopen("fun.bin","wb");
    if(fp==NULL) return(1);
    fwrite(fun,1,sizeof(fun),fp);
    fclose(fp);
    return(0);
}

编译并运行它(是来自exe的exe)并且它生成了一个在hexdump中显示的相同二进制文件:

0000000 d902 e3a0 0000 eb00 fffe eaff 0001 e080
0000010 ff1e e12f                              
0000014

我也可以只使用十六进制编辑器并输入这些字节,而不是使用语言来创建这个二进制文件。虽然它仍然是exe的exe,因为我使用了一个程序的hexeditor。而且我说这里的exe很松散,因为这不是.exe文件格式,而是exe,因为它是一个可执行程序,虽然大多没用。

是的我很清楚在调用fun之前我没有加载r0或r1,并不重要的是处理器寄存器用它们中的位唤醒(除了在一些硅模拟中,这些模拟不是两个状态而是三个,四个或更多状态并且取决于在逻辑设计上)所以添加将起作用。

答案 2 :(得分:0)

  

我可以在没有任何程序的情况下创建独立的Windows应用程序   Visual Studio / Visual Basic?

理论上可能,如果你有时间花费(比如几百年),如果你真的想要使用六进制代码,那就太繁琐了,即使是汇编程序,这几乎是机器之前的最低级别 - 代码,就是说,人类友好...... 要恢复:你不要用刀和竹子来建造泰坦尼克号!