組合語言呼叫Linux系統呼叫read和write
.section .data UserMsg: .ascii "Please input the message:" LenOfUserMsg: .equ lenMsg, LenOfUserMsg - UserMsg #.section .bss # .lcomm resb, 200 OutputMsg: .ascii "This is your input:" LenOfOutputMsg: .equ lenOutput, LenOfOutputMsg - OutputMsg .section .bss .lcomm resb,200 .section .text .globl _start _start: #display UserMsg movl $4, %eax movl $1, %ecx movl $UserMsg, %ecx movl $lenMsg, %edx int $0x80 #Read what input movl $3, %eax movl $0, %ebx movl $resb, %ecx movl $200, %edx int $0x80 #dispaly what you input movl $4, %eax movl $1, %ebx movl $OutputMsg, %ecx movl $lenOutput, %edx int $0x80 movl $4, %eax movl $1, %ebx movl $resb, %ecx movl $200, %edx int $0x80 movl $1, %eax movl $0, %ebx int $0x80
程式碼就是這樣的。要做什麼呢?
很簡單:執行後,命令列提示你輸入數字或者是字元,然後回車,把你輸入的現實出來。
顯然,這個用C語言實現起來簡直太簡單了。
但是,用匯編實現起來同樣很簡單。
==========知識準備============
在彙編中使用系統呼叫,只要是將系統呼叫號複製到eax暫存器。
檢視/usr/include/i386-linux-gnu/asm中的unistd_32.h(64bit機器是/usr/include/x86_linux_gnu/asm/unistd.h/unistd_64.h)
可以看到每個系統呼叫都有一個系統呼叫號。
然後,系統呼叫必然要使用終端。這裡使用的是軟中斷。int $0x80
比如,要使用exit這個系統呼叫
movl $1, %eax
int $0x80
某些系統呼叫有引數,怎麼辦呢?
在C樣式函式中,輸入引數存放在堆疊中;系統呼叫與之不同,需要輸入引數被存放在暫存器中。每個輸入值按照特定的順序放到暫存器中。
簡而言之。
按照順序:
ebx (第1個輸入引數)
ecx (第2個輸入引數)
edx (第3個輸入引數)
esi (第4個輸入引數)
edi (第5個輸入引數)
具體的輸入順序,就取決於系統呼叫中引數的順序。比如,write(fd, *buf, count)
那麼,ebx就是fd,ecx就是*buf,edx就是count
=========程式程式碼簡要說明=============
ebx:檔案描述符
ecx:指向要寫入的字串的指標
edx:要寫入的字串長度
write系統呼叫的值是4,將它存到eax暫存器中。然後將各個引數存放到相應的暫存器中。
需要指出,Linux中,0表示標準輸入一般是鍵盤,1表示標準輸出一般是終端螢幕。
首先在終端螢幕列印字元,提示你輸入。輸入後,使用read存放到一個記憶體區域。
在使用,write將相應區域的輸入值打印出來。
要指出的是,$UserMsg將標籤的記憶體地址存放到ecx中,而不是將實際存放在記憶體中的值放在ecx中。