汇编语言之间的差异

Differences between Assembly Languages

我对汇编语言还很陌生,我知道有很多很多类型的汇编语言。比如ARMMIPSx86等。所以我有疑问。

下面是更多信息

ARM 中的 Hello World

.text            
.global _start
_start:
    mov r0, #1
    ldr r1, =message
    ldr r2, =len
    mov r7, #4
    swi 0

    mov r7, #1
    swi 0

.data
message:
    .asciz "hello world\n"
len = .-message 

Hello World NASM

section .data                        ; section to define memory
    msg db  "Hello, World!", 10      ; define string to the name 'msg', 10 is '\n' character
    len equ $ - msg                  ; assign the length of the string to the name 'len'
        
section .text                        ; section to put code
    global _start                    ; a global label to be declared for the linker (ld)
        
_start:
    mov rax, 1                       ; syscall ID number (sys_write)
    mov rdi, 1                       ; file descriptor (stdout)
    mov rsi, msg                     ; address of string to write
    mov rdx, len                     ; length of string
    syscall                          ; call kernel
        
    mov rax, 60                      ; syscall ID number (sys_exit)
    mov rdi, 0                       ; error code 0
    syscall                          ; call kernel

GAS 语法中的 Hello World

.data
hello:
    .string "Hello world!\n"

.text
.globl _start
_start:
    movl , %eax # write(1, hello, strlen(hello))
    movl , %ebx
    movl $hello, %ecx
    movl , %edx
    int  [=12=]x80

    movl , %eax # exit(0)
    movl [=12=], %ebx
    int  [=12=]x80

MIPS 汇编中的 Hello World

        .data
msg:   .asciiz "Hello World"
    .extern foobar 4

        .text
        .globl main
main:   li $v0, 4       # syscall 4 (print_str)
        la $a0, msg     # argument: string
        syscall         # print the string
        lw $t1, foobar
        
        jr $ra          # retrun to caller

我在网上搜索了很多关于这些的资料。

所以我找到了这个信息:

我有问题想问你:

  1. 虽然汇编语言变了,但代码编写顺序不一样吗?
  2. 汇编语言之间的唯一区别是它们使用的语法?

更多信息

GAS : At&T Syntax

movq    , %r8                 # %r8 = 2
movq    , %r9                 # %r9 = 3
movq    , %r10                # %r10 = 5
imulq   %r9, %r10               # %r10 = 3 * 5 = 15
addq    %r8, %r10               # %r10 = 2 + 15 = 17

NASM : INTEL Syntex

mov r8, 2               ; r8 = 2
mov r9, 3               ; r9 = 3
mov r10, 5              ; r10 = 5
mul r9, r10             ; r10 = 3 * 5 = 15
add r8, r10             ; r10 = 2 + ( 15 ) = 17

汇编语言是由工具定义的,而不是目标。你可以有 100 个汇编器来处理一些不再改变的东西,比如 pdp-11,这意味着 2 到 100 种不兼容的汇编语言。都是作者心血来潮

ARM、x86、risc-v、mips 等是具有理想不兼容机器代码的不同体系结构。因此,作者选择的汇编语言自然会反映体系结构。

creator/inventor 的处理器供应商将提供文档,并且以某种形式,该文档将包括机器代码以及示例汇编语言和描述。该汇编语言倾向于遵循由该处理器供应商创建或为该处理器供应商创建的工具。并非所有供应商都有工具,例如 risc-v 只是以某种方式直接或间接地制作了 gnu 端口,但在过去供应商拥有一些工具并不少见,即使有第三方后来出现的工具。

Intel vs AT&T 不是“语法”,例如有大量不兼容的 Intel 汇编程序以及 AT&T 风格的汇编程序

mov 5h,ax

mov ax,5h 

每个人都适用于历史上的各种工具,但不一定适用于今天的工具;一个会,另一个不会。如果为相同的目标构建(需要 x86 的变体),两者理想地生成相同的机器代码。

没有理由一个汇编程序可以支持

mov r15,r15

另一个

mov pc,lr

还有一个

move pickle,banana

还有一个

return

只要它们生成相同的机器代码(旨在执行相同的指令)。人们希望至少 mov r15,r14 将在 arm 汇编程序(aarch64 之前)中得到支持,但实际上并没有期望它会起作用,每个工具都是它自己的交易。当然,与其他语法相比,其中一种语法不会吸引很多用户。但是它们绝对没有错,因为汇编语言的工作或者至少假设汇编程序所做的是采用一些语法并从中生成机器代码。

x86 是最大的噩梦之一,不仅仅是因为 Intel vs AT&T

在这些领域中存在大量不同的、不兼容的汇编语言,用于 Intel 风格和 AT&T 风格,但没有交叉。在 Intel 风格的世界中,你有 Borland 的 tasm Microsoft 的 masm,它在某种程度上符合 Intel 的文档,因此 Intel 的(当时至少有一个很好的共享软件)和 nasm 试图采用这种语法以及一定比例的兼容性。虽然 ISA 到 gnu binutils 的每个端口可能是不同的 person/team,但我的经验是,gnu 汇编器似乎为它们与同一目标的其他汇编语言不兼容而感到自豪,否则为什么会如此频繁地这样做。 find 的第一个是

mov r0,r1 ; this is a comment

但对于汽油则不然

mov r0,r1 @now this is a comment

当然,我们知道原因,但它并不符合所有目标。 mrs/msr 指令最初与 arm 文档不兼容,此外还有必须遵守的白色 space 规则,现在仍然是 gas 更轻松,更容易应对。

汇编语言不仅仅是助记符,它是整个交易,只要你需要一个标签,你就只能使用助记符,然后是否有冒号,是否有其他标记,它是否必须从第一列开始,是否有除您不能使用的助记符之外的保留字等。所有这些都非常特定于工具作者的选择,而不是体系结构。包括不假定从一种工具移植到另一种工具的伪代码

ldr r0,=0x12345678
ldr r1,=message
pop {r0,r1}
nop

和其他一些(在本例中为 ARM)。还有一些有趣的 gnu,我认为人们用它来愉快地混淆他人

1:

   beq 1b

   b 1f

1:
我上面提到的

pdp-11(lsi-11,随便什么)实际上属于这一类,它目前支持 gcc 和 binutils,来自一家“八进制”公司,大多数关于它的东西都是基于八进制的指令是如何分解成字段的,但是 gnu 端口不是八进制的,反汇编是十六进制的,这使得解析指令变得更加困难。但除此之外,似乎没有任何尝试与为该目标使用了几十年的汇编语言远程兼容(哦,是的,pdp-11 现在仍然是我们生活的主要部分,因为8051 是我们现在生活中很重要的一部分)

Gas and Intel Assembly are same. But syntax is different

绝对不是,尤其是因为“Intel Assembly”本身就是不兼容的。

Syntax is only different for copyright reasons

不,不是原因,个人选择。既然有一个非常好的汇编器,为什么还要创建一个新的汇编器呢?因为你想改变一些东西,现在有了好的免费的,你不能让改变成为价格。

ARM's have their own Syntax type

ARM 是不同于 x86 的架构,有自己的历史,ARM自己的工具已经有三代或更多代了,然后是gnu工具及其至少两代的汇编语言。而且他们很不相容。

Although the assembly languages has changed, is not the code writing order different?

左侧或右侧的目标绝不是 x86 的东西。我认为这可能与您苦苦挣扎的第一种汇编语言有关,因为 asm 是所有编程语言中最简单的。但是一些用于初始目标的初始工具首先是目的地,而另一些则是最后的目的地。 AT&T 令我感到困惑,因为大多数 x86 都是 PC 而不是 Unix 系统,但是由于他们没有使用 Intel 文档作为起点和 gnu 端口选择,所以无论未来会怎样,它就是这样。我上学的时候我们学到了

y = x + 5

没有

x + 5 = y

哦,想想这个

ldr r0,[r1]
str r0,[r2]

而不是

str [r2],r0

The only difference between assembly languages is the syntax they used?

是的,汇编语言当然是一种编程语言,python 和 C 之间的区别是……语法。 C 和 asm 之间的区别在于语法,它们是不同的编程语言,一种汇编语言与另一种工具的另一种汇编语言之间的区别在于语法。我可以有两种语言,其中 x = y + 3 在两者中都是有效语法并不意味着它们兼容或应该兼容。我可以使用 Rust、C、C++ 和 Pascal,甚至 Python 并从中为目标制作机器代码,但这并不意味着语言需要兼容。具体来说,同一目标中汇编语言之间的差异是语法。

当您将一个目标与另一个目标进行比较时,差异也反映了目标指令集架构,没有实际原因,但 x86 语法过度使用 mov,其他人将有单独的加载和存储指令反映这些操作。这些指令集也可以使用 mov 同样,没有理由不使用 x86 语法进行加载和存储。

指令集既常见又不同,如果您从一个好的指令集(pdp-11、msp430、arm original thumb 和一小部分其他指令集)开始学习,那么下一个指令集就是容易得多,最终你可以学习 20 或 30 或 100 没问题,因为它们都倾向于有一个加法,一个减法,一个或,一个 xor 一个加载和存储一个 push 和 pop 以及一个寄存器来注册 move/copy 和其他一些事情。只是标志、寄存器的数量和大小以及立即数的大小和形状不同,当然机器代码也是如此。因此,使用原始运算符的基本编程对某些人来说是一个障碍,除此之外它“只是语法问题”。