简体   繁体   English

68K中的大小写

[英]upper to lower case in 68K

I want to convert from upper to lower case. 我想从大写转换为小写。 this the code I wrote but still not get where is the error. 这是我编写的代码,但仍然无法得到错误所在。 I know to covert from upper to lower I have subtract 32 so that what trying to do it. 我知道从上到下隐蔽地我要减去32,以便尝试这样做。 But, after I run the program it does not show the result in lower case. 但是,运行程序后,它不会以小写形式显示结果。 Thanks for any help. 谢谢你的帮助。

START       ORG    $1000
            MOVE.L USERID,D0
            SUBI.L   #32323232,D0          
            MOVE.L  D0,result            
            SIMHALT 
USERID      DC.L    'ABCD1234'           
result      DS.L    1
            END     START  

#32323232 is ... well, that, value 32323232 . #32323232是...嗯,值32323232 But you tried to apply it to 4 BYTE characters loaded as 32 bit (LONG) value, which means each character occupies it's own 8 bits, like after MOVE.L USERID,D0 the D0 is $41424344 , where $41 == 65 == 'A', $42 == 66 == 'B', $43 == 67 == 'C', $44 == 68 == 'D' . 但是您尝试将其应用于以32位(LONG)值加载的4个BYTE字符,这意味着每个字符都占用了它自己的8位,例如在MOVE.L USERID,D0之后D0$41424344 ,其中$41 == 65 == 'A', $42 == 66 == 'B', $43 == 67 == 'C', $44 == 68 == 'D'

In hexadecimal formatting each letter (8 bits) has exactly two hexadecimal digits, because 1 hexadecimal digit is value from 0 to 15 and that's exactly what 4 bits can encode in total, so it's perfect conversion 4 bits <=> 1 hexadecimal digit. 在十六进制格式中,每个字母(8位)正好有两个十六进制数字,因为1个十六进制数字是从015值,而这恰好是4位总共可以编码的值,因此它是4位<=> 1个十六进制数字的完美转换。

But if you will take that value $41424344 and convert it from hexadecimal to decimal, you will get 1094861636 . 但是,如果您使用该值$41424344并将其从十六进制转换为十进制,则会得到1094861636 It's still the same value, but suddenly the letters are not easily "visible" in it any more. 它仍然是相同的值,但是突然之间字母变得不容易在其中“可见”。 They are hidden there as 65*256*256*256 + 66*256*256 + 67*256 + 68 = 1094861636 , as 8 bits can encode 256 different values, so by multiplying by power of 256 you can place decimal value in particular BYTE of LONG. 它们被隐藏为65*256*256*256 + 66*256*256 + 67*256 + 68 = 1094861636 ,因为8位可以编码256不同的值,因此通过乘以256的幂可以特别设置十进制值LONG的BYTE。 So for example 66*256*256 means "third least significant byte in long", or technically it means to move decimal value 66 "to left by 16 bits". 因此,例如66*256*256表示“长整数的第三个最低有效字节”,或者从技术上讲,它意味着将十进制值66 “左移16位”。 And indeed, if you would load 66 into D1 and do LSL.L #16,D1 , you would calculate 66*256*256 == 66*65536 == (66<<16) without using multiply instruction. 实际上,如果将66装入D1并执行LSL.L #16,D1 ,则无需使用乘法指令就可以计算出66*256*256 == 66*65536 == (66<<16)

It's all about how numbers "base N formatting" works, that you have M digits of (0 to N-1) value, each digit representing multiply of i-th power of N depending on it's position in the number. 关于数字“以N为底的格式”是如何工作的,您拥有M个数字(从0到N-1),每个数字代表N的i次幂的倍数,具体取决于数字在数字中的位置。 Ie. 就是 value 123 in decimal (base 10) formatting is written as "123", where the "1" represents value amount of 10 2 , "2" stands for 10 1 , and "3" is for 10 0 values. 十进制(以10为基数)格式的值123被写为“ 123”,其中“ 1”代表10 2的值量,“ 2”代表10 1的值 ,“ 3”代表10 0的值。

Mind you, the written "123" form is not number 123 . 请注意,书面的“ 123”格式不是123 Number 123 is purely abstract entity, the decimal formatting used to write it down here like "123" is actually imperfect mirror of the value itself, with few limitations imposed by the decimal formatting upon this format, not upon the real value. 数字123纯粹是抽象的实体,用于在此处写下它的十进制格式(如“ 123”)实际上是值本身的不完美镜像,十进制格式对此格式(而不是对实际值)施加的限制很少。 Probably the simplest example of these imperfections of "base N" formats: the value 123 has in decimal second valid form: 122.99999.. with infinite amount of "9" fractions. 可能是“基数N”格式的这些不完美之处的最简单示例:值123以十进制秒的有效形式表示: 122.99999..具有无限数量的“ 9”分数。 It's still the same value 123 exactly, but written differently (and not as practically, as the finitely short "123" variant). 确切地来说,它仍然是相同的值123 ,但是写的方式不同(实际上不像有限短的“ 123”变体那样)。

So back to your 32323232 ... you did want to place each 32 at particular BYTE in LONG, but that would require you to use 32*256*256*256 + 32*256*256 + 32*256 + 32 = 538976288 decimal value. 回到32323232 ...您确实想将每个32放在LONG中的特定BYTE上,但这将要求您使用32*256*256*256 + 32*256*256 + 32*256 + 32 = 538976288十进制值。 Which is PITA to calculate in head. 首先要计算的是PITA。

If you ever wondered "why Assembly sources are full of those annoying hexadecimal numbers?" 如果您想知道“为什么汇编源中充满了那些烦人的十六进制数字?” , here comes the point of this lengthy answer and all of those numerical exercises. ,这是冗长的答案和所有这些数字练习的重点。

32 is $20 (you should be able to convert powers of two in your head on the fly). 32$20 (您应该可以即时转换两个幂)。 And if you want to place $20 at particular byte positions, you have to write #$20202020 (it's still the same 538976288 of course). 而且,如果要将$20放在特定的字节位置,则必须编写#$20202020 (当然还是538976288 )。 That's certainly manageable without calculator, while writing the source, right? 不用计算器,写源代码当然可以解决,对吗? So that's the answer, why the hexadecimal formatting is so popular among Assembly programmers, it allows you to see immediately, what are values of particular bytes in word/long value. 因此,这就是答案,为什么十六进制格式在Assembly程序员中如此流行,它使您可以立即查看word / long值中特定字节的值是什么。

Just for curiosity, your 32323232 value splits into bytes as $01ED36A0 (can you see them now? Each byte is 8 bits = two 4 bits, and 4 bits = single hexadecimal digit). 出于好奇,您的32323232值会拆分为$01ED36A0字节(您现在可以看到它们吗?每个字节为8位=两个4位,而4位=单个十六进制数字)。


And as Mark noted, you need to add. 并且如Mark所述,您需要添加。 So fix of your source: 因此,请修复您的来源:

        MOVE.L   USERID,D0
        ADDI.L   #$20202020,D0
        MOVE.L   D0,result

This will indeed show "abcd" in memory at address result ( $101E ). 这确实会在地址result$101E )的内存中显示“ abcd”。


About "bit manipulation" : if you will take a look at ASCII table with hexadecimal formatting, you will see that the upper/lowercase letter have the same value except the 6th bit, which is clear for uppercase letter, and set for lowercase. 关于“位操作” :如果您看一下采用十六进制格式的ASCII表,您将看到大写/小写字母具有相同的值,但第6位除外(第6位可用于大写字母,而可设置为小写)。

So by doing ORI.L #$20202020,D0 you will set 6th bits in each byte packed in D0 long, effectively doing "to lower case" for letter ASCII values. 因此,通过执行ORI.L #$20202020,D0您将在D0长的每个字节中设置第6位,有效地对字母ASCII值执行“小写”操作。

ANDI.L #~$20202020,D0 ( ~$20202020 is $DFDFDFDF , inverted $20 bit pattern) will do "to upper case" for ASCII letters. ANDI.L #~$20202020,D0~$20202020$DFDFDFDF ,倒置的$20位模式)将对ASCII字母“大写”。

XORI.L #$20202020,D0 will flip upper to lower and lower to upper case, for ASCII letters. XORI.L #$20202020,D0将上下翻转,并降低到大写,以表示ASCII字母。

All of these will meaninglessly mangle other ASCII characters, like digits and symbols, so these bit tricks are usable only when you know your value contains letters only ( "garbage in, garbage out" ). 所有这些都将无意义地破坏其他ASCII字符,例如数字和符号,因此,仅当您知道您的值仅包含字母( “垃圾回收,垃圾回收” )时,这些位技巧才可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM