汇编语言 - 临时字符串输入的寄存器是什么

时间:2016-03-03 07:54:58

标签: assembly emulation emu8086

我一直在比较固定字符串和输入字符串。但很难确定输入的寄存器是什么,是alah或其他什么。我只是一个初学者,对于程序员来说,这是一种痛苦的语言。请帮助我真的很感谢谢谢:)

mov dx, offset temp             ;string input
mov ah, 0ah
int 21h     

mov bl, "a"                     ;condition
cmp al, bl 
jne aw

mov dx, offset msgTrue          ;true
mov ah, 09
int 21h  

aw:                             ;false
mov dx, offset msgFalse
mov ah, 09
int 21h 


ret
    msg  db 10, 13, "           *         ************************************       *****$"
    msg1 db 10, 13, "          ***        *            Ticketing System      *        ***$"
    msg2 db 10, 13, "         *****       ************************************         *$" 
    msg3 db 10, 13, "                          ==========================$" 
    msg4 db 10, 13, "                          =  (a)Land               =$" 
    msg5 db 10, 13, "                          =  (b)Water              =$"
    msg6 db 10, 13, "                          =  (c)Air                =$" 
    msg7 db 10, 13, "                          ==========================$" 
    msg8 db 10, 13, "                           Choose Travel Type: $"
    temp db 2, 0, 3 dup("$") 

    msgTrue db 10, 13, "                           You selected Land$"
    msgFalse db 10, 13, "                           Invalid Input$" 

2 个答案:

答案 0 :(得分:2)

您使用系统调用0Ah(缓冲输入)http://spike.scu.edu.au/~barry/interrupts.html#ah0a,因此您读取的数据位于 temp (缓冲区)

0Ah从STDIN读取n个字节到缓冲区

mov bx, OFFSET buffer将缓冲区的地址(此处为temp)推送到bx中,这是0Ah所需的

要修复读取的字节数,您可以使用例如mov byte [bx],15

另见http://www.fysnet.net/kbbuffio.htm

mov bl, 'a'                     ;condition
cmp al, bl 
jne aw

比较两个8位值(char),见http://x86.renejeschke.de/html/file_module_x86_id_35.html(AL,AH为8位,AX为16位,EAX为32位(扩展AX))

有关8/16- / 32- / 64位命名约定,请参阅此https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture#General-purpose_registers_(16-bit_naming_conventions)

这可用于从输入缓冲区 temp 读取读取输入字节并进行比较:

val DB 'a'
mov al, val                    ;condition
mov bx, OFFSET temp            ; address of temp in bx: bx is a pointer to first byte in temp now
;alternatively you can use  lea bx, [temp] 
add bx, 2                     ; structure of input buffer (here temp) http://spike.scu.edu.au/~barry/interrupts.html#dosbuf
mov dl, byte [bx]              ; writes the byte [bx] points to in dl - [bx] dereferences bx - the byte command treats bx as a char* - see https://www.cs.uaf.edu/2006/fall/cs301/lecture/10_02_pointer.html
cmp al, dl 
jne aw

答案 1 :(得分:1)

结果是在内存中,您要求系统调用它。请参阅拉尔夫的回答。

检查输入如下:

    mov   dx, offset temp             ; input buffer
    mov   ah, 0ah                     ; buffered input syscall
    int   21h     

    ; select one of two messages to print
    mov   dx, offset msgTrue
    cmp   byte ptr [temp+2], 'a'      ; compare the first byte of user input
    je  .true
    mov   dx, offset msgFalse         ; conditionally skip this instruction
.true:

    mov ah, 09                        ; print string syscall
    int 21h

注意mov ah / int 0x21代码只出现一次,而分支只跳过一条指令。您可以在现代CPU上使用cmov执行该操作,但cmov烦人地没有即时源编码。

请参阅有关Ralf的答案的评论,批评臃肿的代码不仅仅是使用cmp的立即操作数。使用汇编时常数时,你也可以通过这种方式减少寄存器数量。

另一个选项(而不是mov dx, offset msgFalse)将是add dx, offset msgFalse - msgTrue,这使得立即操作数变为小数(在-128 .. 127范围内适合使用imm8编码)。但是,它不会在16位代码中保存任何代码字节,因为mov dx, imm16是3个字节(每个dest寄存器的专用操作码),add dx, imm8也是3个字节(没有专用操作码)。这将节省32位代码中的字节,其中地址为32位。