Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 汇编语言-什么是临时字符串输入的寄存器_Assembly_Emulation_Emu8086 - Fatal编程技术网

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

Assembly 汇编语言-什么是临时字符串输入的寄存器,assembly,emulation,emu8086,Assembly,Emulation,Emu8086,我一直在比较固定字符串和输入字符串。但是很难弄清楚输入的寄存器是什么,是al,啊还是别的什么。我只是一个初学者,对于程序员来说,这是一门痛苦的语言。请帮忙我真的很感激谢谢: mov dx, offset temp ;string input mov ah, 0ah int 21h mov bl, "a" ;condition cmp al, bl jne aw mov dx, offset msgTrue

我一直在比较固定字符串和输入字符串。但是很难弄清楚输入的寄存器是什么,是al,啊还是别的什么。我只是一个初学者,对于程序员来说,这是一门痛苦的语言。请帮忙我真的很感激谢谢:

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$" 

您使用syscall 0Ah缓冲输入,以便读取的数据位于临时缓冲区中

0Ah将n个字节从STDIN读入缓冲区

mov bx,OFFSET buffer将缓冲区的地址推到这里,temp在bx中,这是0Ah所需要的

要固定读取的字节数,可以使用例如mov字节[bx],15

也见此

比较两个8位值char,参见此AL,AH为8位,AX为16位,EAX为32位扩展AX

有关8-/16-/32-/64位命名约定,请参见此

这可用于从输入缓冲区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

结果在内存中,您要求系统调用将其放入内存。见拉尔夫的回答

检查输入,如下所示:

    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是每个dest寄存器的3字节专用操作码,加上dx,imm8也是3字节无专用操作码。这将节省32位代码中的字节,其中地址为32位。

为什么不指出cmp al,“a”将更简单?当一个直系亲属的工作方式相同时,不需要捆绑bl。甚至有一个特殊的编码cmp立即与al,所以它只是一个2字节的指令,即使即时。还有,你认为mov bl‘a’有什么不对?大多数汇编器允许您在整数常量出现的任何位置使用字符常量。多字符常量生成多字节整数。与cmp字节[temp],'a'/jne相比,仍然非常笨拙。还要注意,16位有效地址不能使用dx作为基或索引,只能使用BX/BP+SI/DI。这只是16位代码糟糕透顶、浪费学习时间的众多原因之一。这些限制在其他模式中不存在。我不打算这样做,但我不能让低效的代码单独存在感谢您整理输入缓冲区的格式。我不是一个DOS的家伙,我对学习DOS系统调用没有兴趣,只是想帮助别人。哦,顺便说一句,偏移温度+3与偏移温度+3不同。您正在添加ascii编码>。您是对的,它是+2。首先读取时,它认为缓冲区中的字节02也具有“管理功能”,然后开始读取用户字节…代码中的其他问题:[dx]不是有效地址。你的代码无法汇编。使用bx、bp、si或di。e、 g.mov si,偏移温度+2/cmp字节ptr[si],“a”。32位有效地址是相同的,只是没有限制,并且您可以缩放索引。请参阅我先前评论中的链接,了解我在32位EAs上所做的写入操作。如果您愿意,您可以将指令浪费在regs中,但是:请注意,您不需要标记msg1/msg2等。您可以只使用未标记的db行。
    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