汇编语言笔记(GAS, x86-64)

                     

贡献者: addis

  • 本文处于草稿阶段。

   参考一些 x86-64 的例子Tutorials Point(提供一些 cpu 原理,但用的是 NASM 不是 GAS)。

1. 基础

   一个例子:

.global _start

        .text
_start:
        # write(1, message, 13)
        mov     $1, %rax            # system call 1 is write
        mov     $1, %rdi            # file handle 1 is stdout
        mov     $message, %rsi      # address of string to output
        mov     $13, %rdx           # number of bytes
        syscall                     # invoke operating system to do the write

        # exit(0)
        mov     $60, %rax           # system call 60 is exit
        xor     %rdi, %rdi          # we want return code 0
        syscall                     # invoke operating system to exit
message:
        .ascii  "Hello, world\n"

   编译:gcc -c hello.s && ld hello.o && ./a.out,运行:./hello.x

64 位寄存器

32 位寄存器

函数调用

system call 调用

算数命令

gdb 调试

2. Fibonacci 数列

代码 1:fib.s
# A 64-bit Linux application that writes the first 90 Fibonacci numbers.
# gcc -no-pie -g fib.s -o fib.x && ./fib.x

.global main
.text

main:
        push    %rbx                    # we have to save this since we use it
        mov     $10, %ecx               # ecx will countdown to 0
        xor     %rax, %rax              # rax will hold the current number
        xor     %rbx, %rbx              # rbx will hold the next number
        inc     %rbx                    # rbx is originally 1

print:
        # We need to call printf, but we are using  printf
        # may destroy eax and ecx so we will save these before the call and
        # restore them afterwards.
        push    %rax                    # caller-save register
        push    %rcx                    # caller-save register

        mov     $format, %rdi           # set 1st parameter (format)
        mov     %rax, %rsi              # set 2nd parameter (current_number)
        xor     %rax, %rax              # because printf is varargs

        # Stack is already aligned because we pushed three 8 byte registers
        call    printf                  # printf(format, current_number)

        pop     %rcx                    # restore caller-save register
        pop     %rax                    # restore caller-save register

        mov     %rax, %rdx              # save the current number
        mov     %rbx, %rax              # next number is now current
        add     %rdx, %rbx              # get the new next number
        dec     %ecx                    # count down
        jnz     print                   # if not done counting, do some more

        pop     %rbx                    # restore rbx before returning
        ret

format:
        .asciz  "%20ld\n" # null terminated string

                     

© 小时科技 保留一切权利