1. 程式人生 > >32位組合語言學習筆記(41)--fgets等函式的使用

32位組合語言學習筆記(41)--fgets等函式的使用



在《32位組合語言學習筆記(13)--函式的呼叫》曾分析過c函式的呼叫過程,對於c函式的預設呼叫約定cdecl,要求函式引數的壓棧順序是從右向左,由呼叫方來清理棧。下面示例程式會使用libc庫的幾個函式:
char *fgets( char *string, int n, FILE *stream );
int printf( const char *format [, argument]... );
int scanf( const char *format [,argument]... );

示例程式如下:

[SECTION .data]			; Section containing initialised data
	
SPrompt  db 'Enter string data, followed by Enter: ',0		
IPrompt  db 'Enter an integer value, followed by Enter:	 ',0
IFormat  db '%d',0
SShow    db 'The string you entered was: %s',10,0
IShow    db 'The integer value you entered was: %5d',10,0
	
[SECTION .bss]		; Section containing uninitialized data

IntVal   resd	1	; Reserve an uninitialized double word
InString resb 128	; Reserve 128 bytes for string entry buffer
		
[SECTION .text]		; Section containing code

extern stdin		; Standard file variable for input
extern fgets
extern printf	
extern scanf		
global main		; Required so linker can find entry point
	
main:
    push ebp	; Set up stack frame for debugger
	mov ebp,esp
	push ebx	; Program must preserve ebp, ebx, esi, & edi
	push esi
	push edi
;;; Everything before this is boilerplate; use it for all ordinary apps!

; First, an example of safely limited string input using fgets:
	push SPrompt	; Push address of the prompt string
	call printf	; Display it
	add esp,4	; Stack cleanup for 1 parm
	
	push dword [stdin]  ; Push file handle for standard input
	push 72		; Accept no more than 72 chars from keybd
	push InString	; Push address of buffer for entered chars
	call fgets	; Call fgets
	add esp,12	; Stack cleanup: 3 parms X 4 bytes = 12

	push InString	; Push address of entered string data buffer
	push SShow	; Push address of the string display prompt
	call printf	; Display it
	add esp,8	; Stack cleanup: 2 parms X 4 bytes = 8

; Next, use scanf() to enter numeric data:
	push IPrompt	; Push address of the integer input prompt
	call printf	; Display it
	add esp,4	; Stack cleanup for 1 parm

	push IntVal	; Push the address of the integer buffer
	push IFormat	; Push the address of the integer format string
	call scanf	; Call scanf to enter numeric data
	add esp,8	; Stack cleanup: 2 parms X 4 bytes = 8

	push dword [IntVal]	; Push integer value to display
	push IShow	; Push base string
	call printf	; Call printf to convert & display the integer
	add esp,8	; Stack cleanup: 2 parms X 4 bytes = 8
	
;;; Everything after this is boilerplate; use it for all ordinary apps!
	pop edi		; Restore saved registers
	pop esi
	pop ebx
	mov esp,ebp	; Destroy stack frame before returning
	pop ebp
	ret		; Return control to Linux

程式分析:
    這裡只分析fgets函式的呼叫,其他類似。
push dword [stdin]  //stdin是libc庫中的符號,表示標準輸入,實際是一個地址,fgets呼叫需要的是一個控制代碼,而不是地址值,因此要通過間接定址獲取控制代碼值。(對應的入參是stream)
 push 72  //從標準輸入讀取的最大字串長度是72。
 push InString //快取地址,InString分配的空間是128個位元組,所以最大長度設為72是沒有問題的。
 call fgets //呼叫fgets
 add esp,12 //清理堆疊,壓入了3個引數,使用了12個位元組。

makefile檔案內容:

charsin: charsin.o
	gcc charsin.o -o charsin
charsin.o: charsin.asm
	nasm -f elf -g -F stabs charsin.asm

測試:

[[email protected] charsin]# make
nasm -f elf -g -F stabs charsin.asm
gcc charsin.o -o charsin
[[email protected] charsin]# ./charsin
Enter string data, followed by Enter: hello world
The string you entered was: hello world

Enter an integer value, followed by Enter:       123456
The integer value you entered was: 123456

相關推薦

32組合語言學習筆記(41)--fgets函式的使用

 在《32位組合語言學習筆記(13)--函式的呼叫》曾分析過c函式的呼叫過程,對於c函式的預設呼叫約定cdecl,要求函式引數的壓棧順序是從右向左,由呼叫方來清理棧。下面示例程式會使用libc庫的幾個函式: char *fgets( char *string, int

32組合語言學習筆記(32)--loop指令

 loop指令用ecx來控制迴圈次數,loop label,相當於如下兩條指令: dec ecx jne label 如下是使用loop指令的一個示例程式: section .data EditBuff: db 'abcdefghijklm',10 BUFFERL

32組合語言學習筆記(12)--分析switch語句的彙編程式碼

switch語句可以根據整數索引值進行多重分支選擇,程式碼的可讀性好,switch語句的彙編實現是通過跳轉表來完成的,這樣執行效率也很高。int switch_eg(int x){int result = x;switch (x) {case 100:result*= 1

32組合語言學習筆記(21)--用NASM實現Hello World小程式

前面20篇彙編學習筆記主要是學習《深入理解計算機系統》過程中所記錄的筆記,接下來打算學一下另外一本書《Assembly Language step by step programming with linux》。首先需要安裝NASM彙編器,例如:rpm –ivh nasm-2

python學習筆記(41) 設定控制檯顏色

設定開始 \033[顯示方式;前景色;背景色m 前景色  背景色  顏色 30    40    黑色 31    41    紅色 32    42    綠色 33    43    黃色 34    44    藍色 35    45    紫紅色 36    46    青藍色 37

Elasticsearch學習筆記05·ElacticSearch搜尋引擎原理

一、分詞 我 今天 要去 天安門 看 升旗 天安門 每天 早上 升旗 是 幾點 二、檢索   三、索引 1)倒排檢索 query(1⃣️天安門(term)2⃣️升旗(term)3⃣️是(term)4⃣️幾點(term))  

leetcode學習筆記41

這是一道單詞查詢樹的問題, 這裡講的比較詳細 https://www.cnblogs.com/justinh/p/7716421.html class Trie { class TrieNode { // R links to node children priv

32彙編指令筆記

32位CPU所含有的暫存器有: PQJI~u9te} 4個數據暫存器(EAX、EBX、ECX和EDX) <,\Op=$l3I 2個變址和指標暫存器(ESI和EDI) 2個指標暫存器(ESP和E

菜鳥的組合語言學習筆記

 1.1機器語言 計算機發展初期,人們都是用機器語言進行程式設計的,這也是人們能實現程式設計控制計算機的最低級別。那麼機器語言是什麼樣子的呢?就是用0和1組成的一個串(形如011010101),cpu的每一個功能對應著一個串,cpu得到這樣的串就去執行對應的功能,我們把這樣的串叫做一條機器指令。cpu提供的

組合語言學習筆記(一)-----基礎知識

一、組合語言組成    組合語言由以下三類組成    1)彙編指令:機器碼的助記符,有對應的機器碼;    2)偽指令:沒有對應的機器碼,有編譯器執行,計算機並不執行    3)其他符號:如:+、-、*、/等,由編譯器識別,沒有對應的機器碼。二、儲存器:    CPU從記憶體

Win32組合語言學習筆記>>第二課:編寫第一個Win32彙編程式

本節課主要是編譯連線一段寫好的程式碼: 程式執行如下: 程式碼: .386 .model flat,stdcall option casemap:none include C:\masm32\include\windows.inc include C:\masm32\

組合語言學習筆記(十二)-浮點指令

浮點數如何儲存 浮點數的運算完全不同於整數,從暫存器到指令,都有一套獨特的處理流程,浮點單元也稱作x87 FPU。 現在看浮點數的表示方式,我們所知道的,計算機使用二進位制儲存資料,所表示的數字都具有確定性,那是如何表示浮點這種具有近似效果的資料呢,答案是通過科學計數

Eratosthenes篩法求1——100000之間所有的素數(32組合語言

include io32.inc .dataarray byte 100001 dup(30h) .codestart:mov esi,2 ;用來記錄某數,方便以後找所有可以被其整除的數xor edi

python學習筆記-41 多線程

ask 獲取鎖 解釋器 可能 targe -a 機會 python學習 count() 多任務可以由多進程完成,也可以由一個進程內的多線程完成。 我們前面提到了進程是由若幹線程組成的,一個進程至少有一個線程。 由於線程是操作系統直接支持的執行單元,因此,高級語言通常都內

Go語言學習筆記(五) 函式

函式定義 函式構成程式碼執行的邏輯結構。在Go語言中,函式的基本組成為:關鍵字func、函式名、引數列表、返回值、函式體和返回語句。 func (p mytype) funcname(q int) (r, s int) { return 0, 0 }   func:

python學習筆記:取整函式

三種取整方式: 一、向下取整:即捨去小數點後所有資料。int (n),例如: int(3.67) #figure out 3 二、四捨五入:round(n),例如: round(4.56) #figure out 5 round(-4.56) #figure o

數論學習筆記之尤拉函式

最近又開始搞數論了……今天是尤拉函式,對於一些性質或定理,我可能會證明啥的 首先尤拉函式\(\varphi(n)\)指不超過\(n\)與\(n\)互素的數的個數。比如\(\varphi(8) = 4\) 性質:對於\(n = {p_1}^{a_1} * {p_2} ^ {a_2} * {p_3} ^ {a_

python3語言學習筆記(五:函式

使用者自定義函式定義規則: 函式程式碼塊以 def 關鍵詞開頭,後接函式識別符號名稱和圓括號 ()。 任何傳入引數和自變數必須放在圓括號中間,圓括號之間可以用於定義引數。 函式的第一行語句可以選擇性地使用文件字串—用於存放函式說明。 函式內容以冒號起始,並且縮排。

rust學習筆記基礎篇6–函式函式指標(霜之小刀)

rust學習筆記基礎篇6–函式與函式指標(霜之小刀) 歡迎轉載和引用,若有問題請聯絡 若有疑問,請聯絡 Email : [email protected] QQ:2279557541 直接看函式的使用示例 //無返回值無引數的函式 fn

C++學習筆記——關於STL sort()函式的第三個引數問題

STL    sort()函式有三個引數的過載型別 template<class RandomAccessIterator, class Predicate> void sort( RandomAccessIterator first,