Assembly Mips汇编程序-如何获取.ascii的长度
我是这个社区的新手。我们正在大学里编写mips,我需要一个解决我作业中问题的方法。 我们必须打开一个.pgm文件并读取所谓的头文件(在本例中为p5格式和可变长x宽)。当你打开你读过的文件时,你会得到4行,第一行。p5;第二。长x宽;第三个是颜色深度,第四个是ascii码的长期。 我现在的工作是转换这个ascii码,我想我必须知道这个ascii码的大小。 以前,我有一个用于转换ascii的mips代码,但这里的问题是,该代码只转换了我的ascii术语的一部分,如下所示(注释为德语-对此表示抱歉):Assembly Mips汇编程序-如何获取.ascii的长度,assembly,mips,assemblies,mips32,mips64,Assembly,Mips,Assemblies,Mips32,Mips64,我是这个社区的新手。我们正在大学里编写mips,我需要一个解决我作业中问题的方法。 我们必须打开一个.pgm文件并读取所谓的头文件(在本例中为p5格式和可变长x宽)。当你打开你读过的文件时,你会得到4行,第一行。p5;第二。长x宽;第三个是颜色深度,第四个是ascii码的长期。 我现在的工作是转换这个ascii码,我想我必须知道这个ascii码的大小。 以前,我有一个用于转换ascii的mips代码,但这里的问题是,该代码只转换了我的ascii术语的一部分,如下所示(注释为德语-对此表示抱歉):
.data
str:.ascii“GV_]VTI=97:@JPH9326;>CHTPB4/+.6起初我误解了你的问题,但我仍然认为我的回答也是真实答案的一部分,所以首先:
一个问题应该是“如何找到标题的结尾和图像数据的开头”
的最后一个字符是“最大灰度值后的第一个空格字符”。因此您必须按值解析整个标题值,直到解析最大灰度值,然后下一个字节应该是空格(32
(空格)、9
(制表符)、13
(CR)、10
(LF)、11
(VT)、12
(FF)),然后开始像素数据
这是一种非常愚蠢的格式,因为我敢打赌DOS中的某些人确实在灰度最大值之后生成了一些带有“13,10”CR+LF的图像,但…这不是你的问题(或者在加载到内存后检查文件,它读了什么)
现在回到你真正的问题上来
首先,这些数据不是ASCII。它们是二进制像素数据。您的“GV”已经是值为71和86的两个像素。当您将其显示为ASCII字符串时,当然71显示为“G”,但这与任何方式都不相关。PGM的所有“ASCII”都只是报头,在检测到报头的结尾后,二进制数据就会涌入
这些二进制数据的大小是width*height*bytes\u/u pixel
bytes\u/u pixel
对于gray\u max<256
是1,对于gray\u max
在256..65535范围内是2
当每像素使用2个字节时,最高有效字节位于第一位(因此值4097
编码为字节:16,1
,值71编码为:0,71
)
如果您有一些0-255灰度图像,标题中的“最大灰度”设置为255,那么您只需将文件中剩余的(宽度*高度)
字节作为二进制数据(在最后一个标题字符之后)读取,就是这样,这些是您的像素数据,从上到下逐行读取
如果max_gray是其他值,如40或15000,那么您是否应该以某种方式将像素数据转换为0-255 8位范围(在第一种情况下“放大”它们,在第二种情况下“缩小”,如果希望成为专业PGM阅读器,可能通过某种伽马变换).但我预计你的学校任务只有0-255张图像,没有实施伽马校正。不清楚你想要转换什么。这显然不是一个数字?
.data
str: .ascii "GV_]VTI=97:@JPH<1-/6;L\pz ¶³¶»ÃËËÄ»°y{xzk`L@@?>9326<DD:1.--++*-./-//000002222344///35;@LVau ¥´¬§»Çĸ³³»ª °¿Åù±¯¦||x{{yttw{sv}¡°¸±¡¡£¢£p_Z[_hfYUW^accacdehhhhdghjjlnnonnnljifjgfdggfdiiiillllglrvtkiltzx~«ÀÖ¿°©´¾ÃÇÈ×ßãÖÇ»º¡±¼ËÙENSOIHD>;>CHTPB4/+.6<JWizª¯®°¸ÃËËÄ»¶xvj\NECDB<735:?:40//---,+,--./00000222235400259=DNXdw£®³½Á½³¯¯²¢¥§°»ÃÆõ©«}z{|xtmmqus¡±À¹¦m`ZZ^ce\WZ^abcacdehhhhdghjjlnnonnnlljijhggihhfiiiillmljnuxvnlqw~|¤¶ÐáÕÉÅÇÈÇÉÌÝàÒľ³µª¡¡¤±¼ËÙBGIHB@??DILNRI=1,*-6=ISao §¨·ÃËËÄ»º¯wpg\SIEDC>83359520110//.--,-//0000022224751139=CGOXfx£®¼¶®¨¤£¥°»À»¾¼³©¥vnjjmsz¬ÅÅƳxxttxuja[Y[_c`^]^abcacdfhhhhdghjjlnnnnnnonkjlkihjjhghhhhkkjknsy}vpqw~¸ÏãéáÝ×ÓÌÁÂÈÙ඲ª¬¥¦¢§ ¡¨±¼ÌÙ@DFKC?=@CFFA<82.+)-6>IO[e| £«´ÅËËļÁ¹vndbVKACA<632247322321011/.-.//000022225772/4<AFIQYhx¢°½{¡±½½±²¶´®|lmos¸ÍÌ®tpmjgnnjc[XX[`a`_^abcacdfhjhhdghjjlnoonnnpomknmkjljihggggjjjjsv{wrs}¸ÑãíêÝß×ÏǸ´½ÐÛµ²§¡¨¡ª ¢«²¤¡«±ºÌÙ:ADEA>:5;94268501051"
# it converts just to: GV_]VTI=97:@JPH<1
.text
main:
addi $s0, $zero, 0 # $s0 :=0; hier wird das Ergebnis aufsummiert
la $s1,str # $s1 := &str; hier wird der Zeiger auf das nächste Zeichen gehalten
addi $s2, $zero, 10 # $s2 := 10; hier steht konstand die 10 zur Multiplikaton
addi $s3, $zero, 48 # s3 := 48; hier 48, um die ASCII "0" in den Wert 0 umzuwandeln
loop:
lb $s4,($s1) # Lade nächstes Zeichen des
sub $s4, $s4, $s3 #Bilde ASCII-Ziffer auf Integer-Wert [0..9] ab
bltz $s4,terminate # Wenn Zeichen <0,
mult $s0, $s2
mflo $s0 # §s0 := §s0 *10
add $s0, $s0, $s4 # s0= s0 + Ziffernwert
addi $s1, $s1, 1 # s1= s1+1; also auf die nächstes Zeichn im String
j loop
terminate:
li $v0,1 # Resultat ausgeben
or $a0, $zero, $s0 # in ss0 stand das Ergebnis
syscall
li $v0,10
syscall