汇编语言笔记(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


致读者: 小时百科一直以来坚持所有内容免费无广告,这导致我们处于严重的亏损状态。 长此以往很可能会最终导致我们不得不选择大量广告以及内容付费等。 因此,我们请求广大读者热心打赏 ,使网站得以健康发展。 如果看到这条信息的每位读者能慷慨打赏 20 元,我们一周就能脱离亏损, 并在接下来的一年里向所有读者继续免费提供优质内容。 但遗憾的是只有不到 1% 的读者愿意捐款, 他们的付出帮助了 99% 的读者免费获取知识, 我们在此表示感谢。

                     

友情链接: 超理论坛 | ©小时科技 保留一切权利