Say hello to x86_64 Assembly [part 6]

title: Say hello to x86_64 Assembly [part 6]

date: 2020-01-11 23:42:08

tags:

  • x86

  • x64

  • 汇编

  • assembly


翻译原文地址

Say hello to x86_64 Assembly [part 6]

这是Say hello to x86_64 Assembly的第六部分,在这里我们将研究AT&T汇编程序语法。以前我们在所有部分都使用nasm assembler,但是还有其他一些具有不同语法的汇编程序fasm、yasm和其他。正如我在上面写的,我们将研究gas(GNU汇编程序)及其语法和nasm之间的区别。GCC使用GNU汇编程序,因此如果您在汇编程序输出中看到简单的hello world:

It is sixth part of Say hello to x86_64 Assembly and here we will look on AT&T assembler syntax. Previously we used nasm assembler in all parts, but there are some another assemblers with different syntax, fasm, yasm and others. As i wrote above we will look on gas (GNU assembler) and difference between it’s syntax and nasm. GCC uses GNU assembler, so if you see at assembler output for simple hello world:

#include <unistd.h>
​
int main(void) {
  write(1, "Hello World\n", 15);
  return 0;
}
  .file "test.c"
  .section  .rodata
.LC0:
  .string "Hello World\n"
  .text
  .globl  main
  .type main, @function
main:
.LFB0:
  .cfi_startproc
  pushq %rbp
  .cfi_def_cfa_offset 16
  .cfi_offset 6, -16
  movq  %rsp, %rbp
  .cfi_def_cfa_register 6
  movl  $15, %edx
  movl  $.LC0, %esi
  movl  $1, %edi
  call  write
  movl  $0, %eax
  popq  %rbp
  .cfi_def_cfa 7, 8
  ret
  .cfi_endproc
.LFE0:
  .size main, .-main
  .ident  "GCC: (Ubuntu 4.9.1-16ubuntu6) 4.9.1"
  .section  .note.GNU-stack,"",@progbits
.data
    //
    // 初始化数据定义 initialized data definition
    //
.text
    .global _start
​
_start:
    //
    // 主程序 main routine
    //
.section .data
    // 1 byte
    var1: .byte 10
    // 2 byte
    var2: .word 10
    // 4 byte
    var3: .int 10
    // 8 byte
    var4: .quad 10
    // 16 byte
    var5: .octa 10
​
    // assembles each string (with no automatic trailing zero byte) into consecutive addresses
    str1: .asci "Hello world"
    // just like .ascii, but each string is followed by a zero byte
    str2: .asciz "Hello world"
    // Copy the characters in str to the object file
    str3: .string "Hello world"
mov destination, source
mov source, destination
;;
;; nasm syntax
;;
mov rax, rcx
​
//
// gas syntax
//
mov %rcx, %rax
movb $10, %rax
mov ax, word [rsi]
movw (%rsi), %ax
movq -8(%rbp),%rdi
movq 8(%rbp),%rdi
lcall $section, $offset
    # - 单行注释 single line comments
    // - single line comments
    /* */ - 多行注释 for multiline comments

GNU assembler supports 3 types of comments:

GNU汇编程序支持3种类型的注释:

Comments

注释

Far jump - a jump to an instruction located in a different segment than the current code segment but at the same privilege level, sometimes referred to as an intersegment jump.

远跳转-跳转到位于不同于当前代码段但处于相同权限级别的段中的指令,有时称为段间跳转。

GNU assembler supports following operators for far functions call and jumps:

GNU汇编程序支持以下运算符用于远跳转函数调用和跳转:

Jumps

跳转

You can note that we used () brackets in previous example instead [] in nasm example. To dereference values in parentheses are used GAS: (%rax), for example:

您可以注意到,我们在前面的示例中使用了()括号,而在nasm示例中使用了[]。要解引用括号中的值,请使用GAS:(%rax),例如:

Memory access

内存访问

This rule is not only mov instruction, but also for all another like addl, xorb, cmpw and etc…

这个规则不仅是mov指令,而且还适用于所有其他指令,如addl、xorb、cmpw等…

  • b - 1 byte operands

  • w - 2 bytes operands

  • l - 4 bytes operands

  • q - 8 bytes operands

  • t - 10 bytes operands

  • o - 16 bytes operands

GNU assembler has 6 postfixes for operations:

  • b - 1 byte 操作符

  • w - 2 bytes 操作符

  • l - 4 bytes 操作符

  • q - 8 bytes 操作符

  • t - 10 bytes 操作符

  • o - 16 bytes 操作符

GNU汇编程序有6个操作后缀:

There is another way for such operations in gas. We don’t define size in operands but in instruction:

在gas中进行此类操作还有另一种方法。我们不在操作数中定义大小,而是在指令中定义大小:

Sometimes when we need to get part of memory, for example first byte of 64 register, we used following syntax:

有时当我们需要获得部分内存时,例如64寄存器的第一个字节,我们使用以下语法:

Size of operands and operation syntax

操作数大小和操作语法

Also you can not here that registers starts with % symbol. If you’re using direct operands, need to use $ symbol:

另外,不能在这里使用%symbol注册开始元素。如果使用的是直接操作数,则需要使用$符号:

For example:

举例:

With GNU assembler we have back order i.e.:

GNU 汇编有着相反的操作方向,即:

Operands order When we write assembler program with nasm, we have following general syntax for data manipulation:

操作数顺序使用nasm编写汇编程序时,数据操作的一般语法如下:

Also gas uses another directives for data defintion:

  • Section definition starts with . symbol

  • Main routine defines with .globl instead global as we do it in nasm

You can note two little differences here:

你可以在这里注意到两个小小的区别: -节定义以开头以.符号 -主程序定义使用.globl,而不是像我们在nasm中那样使用global gas还使用另一个指令来定义数据:

I don’t know how about you, but when I start to write assembler program, usually I’m starting from sections definition. Let’s look on simple example:

我不知道你怎么样,但当我开始编写汇编程序时,通常是从节定义开始的。让我们看一个简单的例子:

Sections

AT&T syntax

AT&T 语法

Looks different then nasm Hello world, let’s look on some differences.

看起来与nasm不一样的Hello world,让我们看看有些什么不同。

You will see following output:

您将看到以下输出:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值