0

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

以下是更多信息

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 

NASM 中的 Hello World

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 $4, %eax # write(1, hello, strlen(hello))
    movl $1, %ebx
    movl $hello, %ecx
    movl $13, %edx
    int  $0x80

    movl $1, %eax # exit(0)
    movl $0, %ebx
    int  $0x80

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

我在互联网上搜索了很多关于这些的信息。

所以我找到了这个信息。

  • Gas 和 Intel Assembly 是一样的。但是语法不同
  • 语法仅出于版权原因而有所不同
  • ARM 有自己的语法类型

我有问题要问你?

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

更多信息

GAS : At&T Syntax

movq    $2, %r8                 # %r8 = 2
movq    $3, %r9                 # %r9 = 3
movq    $5, %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
4

1 回答 1

4

汇编语言是由工具定义的,而不是目标。你可以拥有 100 个汇编器,比如像 pdp-11 一样不会改变的东西,这意味着有 2 到 100 种不兼容的汇编语言。一切尽在作者的意料之中。

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

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

英特尔与 AT&T 不是“语法”,例如,有大量不兼容的英特尔汇编器以及 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 成为最大的噩梦之一,不仅因为英特尔与 AT&T

在这些领域中,英特尔风格以及 AT&T 风格存在大量不同的、不兼容的汇编语言,而无需交叉。在英特尔风格的世界中,你有 Borland 的 tasm 微软的 masm,它在某种程度上符合英特尔的文档,因此英特尔的(当时也至少有一个好的共享软件)并且 nasm 已经尝试使用这种语法以及一些兼容性百分比。虽然 ISA 到 gnu binutils 的每个端口都可能是不同的人/团队,但我的经验是 gnu 汇编器似乎为它们与同一目标的其他汇编语言不兼容而感到自豪,否则为什么会经常这样做。许多人发现的第一个是

mov r0,r1 ; this is a comment

但对于气体,它不是

mov r0,r1 @now this is a comment

当然,我们知道原因,但它与所有目标不一致。mrs/msr 指令最初与 arm 文档不兼容,此外还有你必须遵守的空白规则,现在仍然是更轻松且更容易处理的气体。

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

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 和 Intel Assembly 是一样的。但是语法不同

绝对不是,特别是因为“英特尔组装”本身就是不兼容的。

语法仅出于版权原因而有所不同

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

ARM 有自己的语法类型

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

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

左侧或右侧的目的地绝不是 x86 的东西。我认为这可能与您遇到的第一个汇编语言有关,如果您甚至挣扎的话,因为 asm 是所有编程语言中最简单的。但是一些初始目标的初始工具是目的地优先,其他的则是目的地最后。AT&T 让我感到困惑,因为大多数 x86 都是 PC 而非 Unix 系统,但无论未来如何,因为它们不使用英特尔文档作为起点和 gnu 端口选择,它就是这样。当我上学时,我们学会了

y = x + 5

不是

x + 5 = y

哦,想想这个

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

代替

str [r2],r0

汇编语言之间的唯一区别是它们使用的语法?

是的,当然汇编语言是一种编程语言,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 没问题,因为所有这些都倾向于有加法、减法、或、异或加载和存储推送和弹出以及用于注册移动/复制和其他一些东西的寄存器。只是标志和寄存器的数量和大小以及立即数的大小和形状会随着机器代码的变化而变化。因此,使用原始运算符的基本编程对某些人来说是一个障碍,除此之外,它“只是语法问题”。

于 2020-09-29T18:13:06.623 回答