X86

X86

X86分為32位元與64位元。

X86-32

32位元使用如下的寄存器。

%eax for syscall_number. 
%ebx, %ecx, %edx, %esi, %edi, %ebp are used for passing 6 parameters to system calls.

eax會放入syscall的號碼。
%ebx, %ecx, %edx, %esi, %edi, %ebp 用來傳遞syscall參數,最多六個參數。

X86-64

64位元使用如下的寄存器。

%rax 會放入syscall的號碼.
%rdi, %rsi, %rdx, %rcx, %r8 and %r9 用來傳遞syscall參數。

可參考 : https://stackoverflow.com/a/2538212/4622645

System Call Table

剛才講到放入systemcall的號碼,可參考如下表格:

http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

Hello World

以下為簡單的印出Hello World 範例。

完成後使用nasm -felf64 hello.asm && ld hello.o && ./a.out 及會印出,但使用Windows系統會有點問題。

a.out為預設compile 完後會產生的檔案名稱。

; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
; To assemble and run:
;
;     nasm -felf64 hello.asm && ld hello.o && ./a.out
; ----------------------------------------------------------------------------------------

          global    _start

          section   .text
_start:   mov       rax, 1                  ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, message            ; address of string to output
          mov       rdx, 13                 ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60                 ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

          section   .data
message:  db        "Hello, World", 10      ; note the newline at the end

1.程式會從global 指定的 start開始執行,一定要命名為_start,而global是給linker看的https://stackoverflow.com/a/17899048/4622645

2.其中section .text 下面放入了read only 與 executable code only

而 section .data 放入了存放的資料。

3.接著讓rax存入1,代表write,讓文字可以寫到Terminal

rdi, rsi, rdx 分別為write的三個參數,可以參考syscall Table表格。

4.跑到syscall 之後即會執行。

可參考不錯的教學範例:http://cs.lmu.edu/~ray/notes/nasmtutorial/

星星範例

以下範例可印出星星

*
**
***
****
*****
******
*******
********
          global    _start
          section   .text
_start:
          mov       rdx, output             ; rdx holds address of next byte to write
          mov       r8, 1                   ; initial line length
          mov       r9, 0                   ; number of stars written on line so far
line:
          mov       byte [rdx], '*'         ; write single star
          inc       rdx                     ; advance pointer to next cell to write
          inc       r9                      ; "count" number so far on line
          cmp       r9, r8                  ; did we reach the number of stars for this line?
          jne       line                    ; not yet, keep writing on this line
lineDone:
          mov       byte [rdx], 10          ; write a new line char
          inc       rdx                     ; and move pointer to where next char goes
          inc       r8                      ; next line will be one char longer
          mov       r9, 0                   ; reset count of stars written on this line
          cmp       r8, maxlines            ; wait, did we already finish the last line?
          jng       line                    ; if not, begin writing this line
done:
          mov       rax, 1         ; system call for write
          mov       rdi, 1                  ; file handle 1 is stdout
          mov       rsi, output             ; address of string to output
          mov       rdx, dataSize           ; number of bytes
          syscall                           ; invoke operating system to do the write
          mov       rax, 60         ; system call for exit
          xor       rdi, rdi                ; exit code 0
          syscall                           ; invoke operating system to exit

          section   .bss
maxlines  equ       8
dataSize  equ       44
output:   resb      dataSize

Last updated