1. 程式人生 > >組合語言呼叫Linux系統呼叫read和write

組合語言呼叫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中。