Assembly 如何使用中断将该字符串转换为大写?

Assembly 如何使用中断将该字符串转换为大写?,assembly,emu8086,Assembly,Emu8086,我写了下面的代码。当我在emu8086中进行模拟时,只需在屏幕上以小写字母显示 我想通过使用另一个中断和函数将这些字符转换成大写。怎样才能做到呢 LEA BX, MSG MOV AH, 2 MOV CX, 26 DON: MOV DL, [BX] INT 21H INC BX LOOP DON

我写了下面的代码。当我在emu8086中进行模拟时,只需在屏幕上以小写字母显示

我想通过使用另一个中断和函数将这些字符转换成大写。怎样才能做到呢

       LEA BX, MSG
       MOV AH, 2
       MOV CX, 26

  DON: MOV DL, [BX]                                                        
       INT 21H
       INC BX
       LOOP DON
       RET

       MSG DB 'study of assembly language'

noneemu8086中断提供从小写到大写的转换服务

自行转换-在使用
int 21h
的“显示输出”功能之前,执行
mov dl[bx]
后,您在
dl
中有字符值。因此,在这两者之间,可以修改character的值

研究一下dl中的数字,以及DOS将在它的屏幕上显示什么。然后想想你想用什么方式操纵哪些数字。将小写ASCII转换为大写ASCII字母可能需要一条
指令,如果您可以安全地假设只有字母通过,但您可能希望将“空格”保留为“空格”,甚至保留数字和其他非字母字符

比如,假设您希望将值从4更改为7,再更改为值[10,11,8,9],并且希望保持其他值不变:

  ; convert DL: values [4, 5, 6, 7] -> [10, 11, 8, 9]
  ; keep other values intact
    cmp dl,4
    jb  keepIntact  ; when DL < 4, jump (jb = jump below)
    cmp dl,7
    ja  keepIntact  ; when DL > 7, jump (ja = jump above)
    xor dl,14       ; do magic (calculates new value)
    ; continue with the same code as values 0-4 and 8-255
keepIntact:
  ; here DL contains patched/intact value, as wanted
我在这本书中找到了关于BIOS和键盘的更详细的描述(看起来由作者出版,个人电子使用合法,不可打印(购买纸质硬拷贝打印版本))

现在我将试着解释更多,这段代码是关于什么的,但一般来说,如果你没有从你的书中得到它,那么我恐怕我简短的解释可能会更糟

在16位模式下,键盘由BIOS中断处理。在这种情况下,“中断”是指处理器的代码,即
int9
,它由微控制器执行,微控制器接收来自键盘设备的输入,将其转换为扫描码,并将该值置于60小时I/O端口。然后,这个
int9
处理程序将扫描代码转换为ASCII(加上根据当前状态ctrl/shift/caps lock/num lock/进行的转换),并使其他程序可以通过BIOS或DOS中断读取键盘。在0040:0017将0F0h放入内存位置将影响
int 9
处理程序,使其认为“大写锁定”是由用户设置的,因此用户的任何下一个字母键盘输入都将是大写的(除非用户在键入时也按住shift键)

一般来说,这是旧DOS时代的内部操作,您不应该注意这一点,它在MS Windows/linux世界中没有任何用处。Emu8086可能部分模拟了这一功能,但我不敢打赌,它主要是模拟
int10h
/
int21h
服务,而且只有很少的服务,我认为它不会模拟整个
int9h
在虚拟0040:0017检查值的内部功能。
dosbox
16位PC仿真器就是这样做的(使许多旧的DOS软件能够正常工作)

但这再一次影响了键盘的状态(我指的是旧的,要么是原始的IBM PC键盘,要么是更“现代”的PS/2键盘。今天许多键盘都是通过USB连接的,处理方式完全不同,需要不同的BIOS处理程序才能工作)


它不转换任何字符串。这让我想知道你到底在问什么。

你不需要中断,只需要在显示DL之前检查DL是否在“a”…“z”范围内:

       LEA BX, MSG
       MOV AH, 2
       MOV CX, 26

  DON: MOV DL, [BX]                                                        
       cmp dl, 'a'
       jb  display   ;◄■■ IF DL < 'a' (JB=JUMP IF BELOW).
       cmp dl, 'z'
       ja  display   ;◄■■ IF DL > 'z' (JA=JUMP IF ABOVE).
       sub dl, 32    ;◄■■ CONVERT LOWERCASE TO UPPERCASE ('a'=97, 'A'=65).
  display:
       INT 21H
       INC BX
       LOOP DON
       RET
LEA BX,MSG
MOV啊,2
莫夫CX,26
DON:MOV-DL[BX]
cmp dl,‘a’
jb显示器;◄■■ 如果DL<'a'(JB=如果低于则跳转)。
cmp dl,'z'
ja显示;◄■■ 如果DL>z(JA=如果在上面则跳转)。
副dl,32;◄■■ 将小写转换为大写('a'=97,'a'=65)。
显示:
INT 21H
公司BX
洛普唐
RET

我研究的那本书说caps lock有一个中断,但我不能使用它,这里有一个关于它的信息:我不能以同样的方式理解它。如果你找到链接并搜索——打开所有键盘上的“锁定”——你可以看到标题。@现在,或者我甚至不知道从哪里开始,因为你把三种不同的东西混在一起。。。1) 您的问题标题是“如何转换字符串”。你的书和你的链接根本不相关。2) 链接是关于打开/关闭键盘上的LED(LED=发光二极管),经典的IBM PC键盘的右上角有三个指示灯,用于报告caps lock/num lock/scroll lock的当前状态。在DOS下,你可以按你所希望的任何方式切换这些灯。我不确定它在一些模拟器中会做什么,可能什么都没有。3) 这本书听起来像是在做你自己的键盘中断。@NoWeDoR-hmm。。再次检查链接源代码,可能不是关于LED,而是关于真正打开DOS键盘处理程序例程的实际“锁”。。。我将试着决定是哪一个,并补充答案。。无论哪种方式,它都不会转换字符串。为什么您会假设有一个DOS或BIOS函数可以将字符串转换为大写?在过去,整个世界都被认为是ASCII码,所以案例转换是一个简单的过程。它不需要是API。您的问题有了新的答案,请查看!
       LEA BX, MSG
       MOV AH, 2
       MOV CX, 26

  DON: MOV DL, [BX]                                                        
       cmp dl, 'a'
       jb  display   ;◄■■ IF DL < 'a' (JB=JUMP IF BELOW).
       cmp dl, 'z'
       ja  display   ;◄■■ IF DL > 'z' (JA=JUMP IF ABOVE).
       sub dl, 32    ;◄■■ CONVERT LOWERCASE TO UPPERCASE ('a'=97, 'A'=65).
  display:
       INT 21H
       INC BX
       LOOP DON
       RET