No an ARM executes ARM instructions a MIPS processor executes MIPS, and so on. There are many many different incompatible instruction sets. A term you can use is machine code or machine language, which is the binary, the bits that make the processor run. Assembly language is ideally a one to one set of human readable mnemonics, a text language easier to program and read than machine code. An assembler takes the assembly language and turns it into machine code.
so take this simple function
unsigned char fun ( unsigned char a, unsigned char b )
{
return(a+b+3);
}
An arm implementation might be
00000000 <fun>:
0: e2811003 add r1, r1, #3
4: e0800001 add r0, r0, r1
8: e20000ff and r0, r0, #255 ; 0xff
c: e12fff1e bx lr
the machine code is the 0xe2811003 part and the assembly language that has a one to one relationship to that instruction is add r1,r1,#3 this processor has registers r0,r1,r2. This compiler conforms to a convention that says the first parameter is passed in r0 the second in r1, so a is in r0, and b in r1, and we need to return in r0 so we add 3 to r1 then we add r1 (which is now b+3) to r0 (which is a) and save it in r0, so r0 now holds a+b+3 since this is unsigned char math, 8 bits, we need to and with 0xFF to keep the result an unsigned char, and then return.
I say one way because with this same code and compiler I can change the compiler options and get
00000000 <fun>:
0: e52db004 push {r11} ; (str r11, [sp, #-4]!)
4: e28db000 add r11, sp, #0
8: e24dd00c sub sp, sp, #12
c: e1a03000 mov r3, r0
10: e1a02001 mov r2, r1
14: e54b3005 strb r3, [r11, #-5]
18: e1a03002 mov r3, r2
1c: e54b3006 strb r3, [r11, #-6]
20: e55b2005 ldrb r2, [r11, #-5]
24: e55b3006 ldrb r3, [r11, #-6]
28: e0823003 add r3, r2, r3
2c: e20330ff and r3, r3, #255 ; 0xff
30: e2833003 add r3, r3, #3
34: e20330ff and r3, r3, #255 ; 0xff
38: e1a00003 mov r0, r3
3c: e28bd000 add sp, r11, #0
40: e49db004 pop {r11} ; (ldr r11, [sp], #4)
44: e12fff1e bx lr
which is an unoptimized version of the same it also implements the C code we asked it to it just is...not optimized... The difference between -O2 and -O0 on the command line.
an x86 version of our simple function
0000000000000000 <fun>:
0: 8d 44 3e 03 lea 0x3(%rsi,%rdi,1),%eax
4: c3 retq
one I like to throw in to see if folks know what it is
00000000 <_fun>:
0: 1166 mov r5, -(sp)
2: 1185 mov sp, r5
4: 9d40 0006 movb 6(r5), r0
8: 65c0 0003 add $3, r0
c: 9d41 0004 movb 4(r5), r1
10: 6040 add r1, r0
12: 1585 mov (sp)+, r5
14: 0087 rts pc
msp430
00000000 <_fun>:
0: 1166 mov r5, -(sp)
2: 1185 mov sp, r5
4: 9d40 0006 movb 6(r5), r0
8: 65c0 0003 add $3, r0
c: 9d41 0004 movb 4(r5), r1
10: 6040 add r1, r0
12: 1585 mov (sp)+, r5
14: 0087 rts pc
and back to arm, arm has a 16 bit instruction set called thumb
00000000 <fun>:
0: 3103 adds r1, #3
2: 1840 adds r0, r0, r1
4: 0600 lsls r0, r0, #24
6: 0e00 lsrs r0, r0, #24
8: 4770 bx lr
So hopefully it is very clear that machine code is in no way universal, and in fact neither are compilers there is more than one way to compile the same high level code to assembly language. Even for the same target with the same compiler.
Note I say compile to assembly language, it is a very common thing to do that, you already have an assembler and linker, compiling to machine code is hard to read so hard to debug for the compiler authors, no reason to do that when you already have an assembler. This is why they are called toolchains. Very common, when you run gcc -o hello hello.c MANY programs are run, just the gcc cmopiler itself is a few programs that execute in order leaving temporary files behind for the next program, then eventually the assembler is called (unless you specified -S and it just stops with assembly language) to assemble it into an object then gcc cleans up the temporary files. Again fairly common, this is why it is called a toolchain, compiler to assembler to linker, a chain a sequence of programs that are run in order.
With gcc for example if I put --save-temps on the command line
so.i
# 1 "so.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "so.c"
unsigned char fun ( unsigned char a, unsigned char b )
{
return(a+b+3);
}
so.s
.cpu arm7tdmi
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 34, 0
.eabi_attribute 18, 4
.file "so.c"
.text
.align 1
.p2align 2,,3
.global fun
.syntax unified
.code 16
.thumb_func
.fpu softvfp
.type fun, %function
fun:
adds r1, r1, #3
adds r0, r0, r1
lsls r0, r0, #24
lsrs r0, r0, #24
@ sp needed
bx lr
.size fun, .-fun
.ident "GCC: (GNU) 6.3.0"
and then it makes the object which is a binary we can use objdump to see as above.
Being a very boring program/function that wasnt very exciting, but if you had includes and includes had includes and so on, one of these intermediate files would be a really big single file with all the includes expanded out so the real compiler only has to work on the one file.