<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中。