史萊姆論壇

史萊姆論壇 (http://forum.slime.com.tw/)
-   程式語言討論區 (http://forum.slime.com.tw/f76.html)
-   -   組合語言作業又來了...小弟誠心拜託大家... (http://forum.slime.com.tw/thread164088.html)

kinco 2005-12-23 12:31 AM

組合語言作業又來了...小弟誠心拜託大家...
 
小弟依然看不太懂他的意思...
這次的題目是要使用者輸入字串~然後大寫換小寫
我不懂怎麼輸入字串阿~冏rz...小弟誠心請大家幫忙~感恩~ :decfghi6:
語法:

WriteString PROC
Writes a null-terminated string to standard output.
Call args: EDX = points to string
Return arg: None
Example:
.data
prompt BYTE "Enter your name: ",0

.code
mov edx,OFFSET prompt
call WriteString
ReadString PROC
Reads a string of up to ECX non-null characters from standard input, stopping when the user presses the Enter key.
A null byte is stored following the characters input, but the trailing carriage return and line feed characters are not placed into the buffer.
ECX should always be smaller than the buffer size (never equal to the buffer size) because the null byte could be the (ECX+1)th character stored.
Call args: EDX points to the input buffer
ECX max number of non-null chars to read

Return arg: EAX = size of input string.
Example:
.data
MAX = 80 ;max chars to read
stringIn BYTE MAX+1 DUP (?) ;room for null
.code
mov edx,OFFSET stringIn
mov ecx,MAX ;buffer size - 1
call ReadString

Crlf PROC
Writes a carriage return/linefeed sequence (0Dh,0Ah) to standard output.
Call args: None

Return arg: None
Example:
call Crlf


mini 2005-12-23 11:42 AM

不知版有有無MASM工具書
個人組合語言也幾乎不記得
而之前的回復是參考以前的舊課本
80x86與MASM 6 組合語言
複習一下 查出來的

言歸正傳
原本最簡單的鍵盤字串輸出入可用
mov ah,0AH
int 21H

輸出用
mov ah,09H
int 21H

但看了一下版友的題目
似乎在輸入的同時作 判斷 轉換
而 WriteString 、ReadString、Crlf 這些副程式就是要實作的地方
語法:

ReadString PROC NEAR
                ...
                RET
SUBP        ENDP

也可用巨集的寫法 (往後使用巨集呼叫越多 程式組譯後會越大)
語法:

ReadString MACRO
                ...
                ENDM

至於內容...

0Dh,0Ah 是一個換行字串
也就是題目所提到的 Enter 鍵

stringIn 是擺放輸入的字串 (記憶體變數)
MAX 最多可輸入字串長度
ECX 計數暫存器,上面是用來記載 standard input(標準輸入裝置,大多是指鍵盤)的buffer長度 (不包含null字元)
EDX 是用來指向buffer的位址
EAX 累加暫存器,上面是用來 表示你輸入了幾個字
(以上 buffer 是指鍵盤的緩衝區)

EDX的使用配合 int 21h的話
語法:

GetStr MACRO buffer
          mov AH ,0aH
          lea  EDX,buffer ;把buffer變數的偏移位址傳入EDX,使buffer變成鍵盤的緩衝區
          int  21H
          ENDM

語法:

    .data
MAX = 80 ;max chars to read
stringIn BYTE MAX+1 DUP (?) ;room for null
    .code
    .startup
    GetStr stringIn ;這樣就會把鍵盤輸入放入stringIn 這個記憶體變數中
    ...
    .exit
    end

最後是字串的輸出
同樣寫成巨集
語法:

ShowStr MACRO message
          mov AH ,09H
          lea  EDX,message
          int  21H
          ENDM

示範一下
語法:

    .data
prompt BYTE "Enter your name: ",0
    .code
    .startup
    ShowStr prompt
    ...
    .exit
    end


kinco 2005-12-23 12:15 PM

我有試著寫了一個~但是執行EXE檔的時候~他沒有出現東西~QQ :decfghi6:
請大大給小弟一點指導~
語法:

INCLUDE Irvine32.inc
.data
prompt BYTE "Enter your name: ",0
MAX = 80 ;max chars to read
stringIn BYTE MAX+1 DUP (?) ;room for null
.code

main PROC
    mov edx,OFFSET prompt ;顯示對話,印出edx裡面的字串
                mov esi,OFFSET stringIn
                mov ecx,MAX ;buffer size - 1
L1:
                mov ah,0AH
                int 21H
    AND byte ptr[esi],1101111b                ;清除位元5
                inc esi
    loop L1

    mov edx, OFFSET prompt
    call ReadString
    call Writestring
    call Crlf  ;空一行
    exit
main ENDP
END main


mini 2005-12-23 01:28 PM

call ReadString
call Writestring
call Crlf
這三行沒有把副程式寫出來...?

不知您用的是什麼組合語言軟體 ?
mov edx, OFFSET prompt
相當於
lea edx,prompt ;把prompt變數的偏移位址傳入edx,使prompt變成鍵盤的緩衝區

這一段
語法:

    mov edx,OFFSET prompt ;顯示對話,印出edx裡面的字串
    mov esi,OFFSET stringIn
    mov ecx,MAX ;buffer size - 1
L1:
    mov ah,0AH
    int 21H
    AND byte ptr[esi],1101111b  ;清除位元5
    inc esi
    loop L1

不知目地為何 ??
如是要 "顯示對話,印出edx裡面的字串"
請參考前面講的
語法:

ShowStr MACRO message
          mov AH ,09H
          lea  EDX,message
          int  21H
          ENDM
...
        ShowStr prompt

mov ah,09h
lea edx,**要顯示的字串** ;獲得其偏移位址
int 21h

kinco 2005-12-23 04:21 PM

我用的是MASM615~後來看了一下
原來是我放錯地方了@@
寫的差不多了~只是有點小BUG~
大轉小是OK的~小轉大有點問題~例如我輸入kinco 他會出現KiNcO
~小弟看了很久~找不到問題在哪~ :decfghi6:
請大大~有發現問題所在的話~告知小弟一下~謝謝~ :ddrf567h:
語法:

INCLUDE Irvine32.inc

.data
prompt BYTE "Enter your name: ",0Dh,0Ah,0 ;定義對話串
MAX = 80 ;max chars to read
stringIn BYTE MAX+1 DUP (?) ;room for null

.code
main PROC               
    mov edx, OFFSET prompt  ;顯示對話
    call WriteString                          ;印出edx裡面的字串
    call crlf                                                  ;空一行

                mov edx, OFFSET stringIn
                mov ecx, MAX ;buffer size - 1
                call ReadString
               
                mov ecx, 0
                mov esi, 0
               
                mov ecx, LENGTHOF stringIn
                mov esi, OFFSET stringIn       
L1:
                mov al,byte ptr[esi]
                OR al, 11011111b
                cmp al, 11111111b                          ;判斷是不是小寫
                je L2                                                                                ;如果是小寫就跳到L2
                jmp L3                                                                        ;如果不是就跳到L3
L2:
                AND byte ptr[esi], 11011111b        ;小->大
                inc esi
L3:
                OR byte ptr[esi], 00100000b  ;大->小
                inc esi
next:
    loop L1
   
    call Writestring
    call Crlf  ;空一行
    exit
main ENDP
END main


mini 2005-12-24 10:43 AM

看了老半天...
後來翻書才找出問題癥結
cmp、or 及 inc 指令會影響 ZF(零值旗標,當運算結果為零時ZF=1)
je 指令會參考 ZF作抉擇 (ZF=1時即為等於 執行跳躍動作)

種種複雜的 ZF變動
如果之前 ZF=1
cmp al, 11111111b 結果 又不對ZF作清除 (cmp是一個減的測試動作 al-ffH 不等於0,ZF不動 ※如果ZF=1 保持1 如果為0 保持0)

則還是會執行(跳到) "小->大"
所以你的結果才會
每隔一個字元才作一次 "大->小"

只要在 cmp al, 11111111b 前將 ZF強制變為 0 即可
針對 FL 旗號暫存器的第6bit作 and FL,1111111110111111b 即可


以上因為沒有MASM作實際測試
所以是不是果真如此...不敢打包票 ^^||

kinco 2005-12-27 03:36 PM

有 ~我改完了~一直忘了貼上來~qq~
語法:

INCLUDE Irvine32.inc

.data
prompt BYTE "Enter your name: ",0Dh,0Ah,0 ;定義對話串
MAX = 80 ;max chars to read
stringIn BYTE MAX+1 DUP (?) ;room for null

.code
main PROC               
    mov edx, OFFSET prompt  ;顯示對話
    call WriteString                          ;印出edx裡面的字串
    call crlf                                                  ;空一行

                mov edx, OFFSET stringIn
                mov ecx, MAX ;buffer size - 1
                call ReadString
               
                mov ecx, 0
                mov esi, 0
               
                mov ecx, LENGTHOF stringIn
                mov esi, OFFSET stringIn       
L1:         
                mov al, byte ptr[esi]
                                  ;判斷是不是小寫
                BT eax, 5                                                                               
                jc L2      ;如果是小寫就跳到L2
                jmp L3                                                                        ;如果不是就跳到L3
L2:
                AND byte ptr[esi], 11011111b        ;小->大
                inc esi
                jmp L1
L3:
                OR byte ptr[esi], 00100000b  ;大->小
                inc esi       
next:
    loop L1
   
    call Writestring
    call Crlf  ;空一行
    exit
main ENDP
END main



所有時間均為台北時間。現在的時間是 03:22 AM

Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2025, Jelsoft Enterprises Ltd.

『服務條款』

* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *


SEO by vBSEO 3.6.1