彙編語言調用Linux系統調用read和write

<span style="font-family:Microsoft YaHei;">.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






</span>

代碼就是這樣的。要做什麼呢?

很簡單:運行後,命令行提示你輸入數字或者是字符,然後回車,把你輸入的現實出來。

顯然,這個用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中。



發佈了31 篇原創文章 · 獲贊 1 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章