/MedianaElka/main.asm
Assembly | 546 lines | 499 code | 47 blank | 0 comment | 16 complexity | eb2e69466da668a6b5e766368019f1d3 MD5 | raw file
1.data 2#filename: .asciiz "qt.bmp" 3#new_filename: .asciiz "output.bmp" 4#.align 2 5filename: .space 64 6new_filename: .space 64 7#.align 2 8thanks: .asciiz "\nProgram zakonczyl dzialanie, wynik dzialania zapisano w pliku " 9question_s: .asciiz "Nazwa pliku do przerobienia (max. 64 znaki) > " 10question_t: .asciiz "Nazwa pliku do zapisania wyniku (max. 64 znaki; UPRAWNIENIA ZAPISU!) > " 11newline: .asciiz "\n" 12processing: .asciiz "Processing.." 13dot: .asciiz "." 14 15.align 2 16fl: .space 4 # current 1st line pointer 17sl: .space 4 # current 2nd line pointer 18tl: .space 4 # current 3rd line pointer 19pl: .space 4 # current proccesed line result 20 21.text 22main: 23 24# Register once set keep their value till the end: 25# s1 - file descriptor of source 26# s2 - width (same for both files) 27# s3 - height (same for both files) 28# s5 - file descriptor of result 29# s6 - bytes in one line with complement 30 31################################################################################## 32## ASKING USER FOR FILENAMES AND PROGRESSING IT 33################################################################################## 34 35 ## SYSCALL (print first question) 36 li $v0,4 # print_string service 37 la $a0,question_s # show place where the string is 38 syscall # printf(question_s) 39 40 ## SYSCALL (take filename of file to process) 41 li $v0, 8 # read_string service 42 la $a0, filename #show place for source filename (global variable) 43 li $a1, 64 # max. filename size is 64 44 syscall # scanf(source_filename, 64) 45 46 ## SYSCALL (print second question) 47 li $v0,4 # print_string service 48 la $a0,question_t # show place where the string is 49 syscall # printf(question_t) 50 51 ## SYSCALL (take filename of file for output) 52 li $v0, 8 # read-string service 53 la $a0, new_filename #show place for target filename (global variable) 54 li $a1, 64 # max. filename size is 64 55 syscall # scanf(target_filename, 64) 56 57 #for(i=0;l[i]!='\n';++i); 58 #l[i]='\0'; 59 # Change first \n to \0 in loaded filenames 60 61 # changing in source_file 62 li $t0, 0 63 la $t1, filename 64 no_nl: 65 addu $t2,$t1,$t0 66 lb $t3,0($t2) 67 bne $t3,10,skip_nl 68 sb $0, 0($t2) 69 j no_nl_end 70 skip_nl: 71 addiu $t0,$t0,1 72 j no_nl 73 no_nl_end: 74 75 76 # changing in target_file 77 li $t0, 0 78 la $t1, new_filename 79 no_nln: 80 addu $t2,$t1,$t0 81 lb $t3,0($t2) 82 bne $t3,10,skip_nln 83 sb $0, 0($t2) 84 j no_nl_endn 85 skip_nln: 86 addiu $t0,$t0,1 87 j no_nln 88 no_nl_endn: 89 90 # Filenames are now valid (without \n in the end). 91 # All register FREE 92 93 94################################################################################## 95## OPENING FILES WITH AND FOR DATA 96################################################################################## 97 98 ## SYSCALL (open file for reading, $s1 is file descriptor) 99 li $v0, 13 # open-file service 100 la $a0, filename # 0($s0) # set filename to read 101 li $a1, 0 # read-only flag 102 li $a2, 0 # ignore mode 103 syscall # open file, $v0 gets file-descriptior 104 move $s1, $v0 # let s1 be file descriptor for old file 105 106 ## SYSCALL (open file for writing (for save the result of program)) 107 li $v0, 13 # open-file service 108 la $a0, new_filename # show file to write to 109 li $a1, 1 # write flag 110 li $a2, 0 # ignore mode 111 syscall # open result file for writing, $v0 gets descriptor 112 move $s5, $v0 # let s5 be file descriptor for new file 113 114 # Now needed files are opened 115 # For now: 116 # $s1 is source file descriptor 117 # $s5 is target file descriptor 118 119 120################################################################################## 121## LOADING PROCESSING AND SAVING HEADER OF BITMAP 122################################################################################## 123 124 addiu $sp,$sp,-54 # make place for header (from old bmp) 125 126 ## SYSCALL (read 54B of file to $t0 (place on stack)) 127 li $v0, 14 # read-from-file service 128 move $a0,$s1 # give system file descriptor 129 la $a1,0($sp) # show place to write ($t0) 130 li $a2,54 # set 54B limit to read (header size) 131 syscall # read header of bmp 132 133 # Read bmp dimensions from header just read 134 lhu $s2,0x12($sp) # read width (stored on 2B) 135 lhu $s3,0x16($sp) # read height (stored on 2B) 136 137 ## SYSCALL (write 54B from stack to result file (header without any changes)) 138 li $v0, 15 # write-to-file service 139 move $a0, $s5 # give system file dscriptor 140 la $a1, 0($sp) # show place to write from ($t0) 141 li $a2, 54 #set 54B as number of bytes to write to file 142 syscall # write header to reslut file 143 144 addiu $sp,$sp,54 # free stack of header information 145 146 # Now header is written to target file 147 # For now: 148 # $s2 is width of image 149 # $s3 is height of image 150 151 152################################################################################## 153## JUST END UP PROGRAM IF FILE IS TO SMALL FOR THIS FILTER 154################################################################################## 155 156 blt $s2,3,exit # if file is to small 157 blt $s3,3,exit # just do nothing about it 158 #@todo: probably it should rewrite image without any changes 159 160 # Now program ends if file is smaller then 3x3 in at least one dimension 161 162################################################################################## 163## CALCULATING LINE SIZE IN BYTES 164################################################################################## 165 166 ## $t1 - 3 constans 167 li $t1,3 168 mult $s2,$t1 # 3 bytes describing one pixel in BMP (R,G,B) 169 mflo $s6 # assuming 32 bits is enough for line size in bytes 170 171 ## $t1 - FREE 172 173 ## $t1 - width mod 4, with is number of bytes in complement 174 andi $t1,$s2,0x00000003 # $t4 = width % 4 175 addu $s6,$t1,$s6 # $s6 - is actual number of bytes in line now 176 177 ## $t1 - FREE 178 179 # For now: 180 # $s6 is number of bytes in line with complement 181 182################################################################################## 183## READING FIRST LINES (SAVING ONE OF THEM), PREPARING STACK FOR 4 LINES (3 readed, 1 for progress) 184################################################################################## 185 186 subu $sp,$sp,$s6 # prepare stack to store the line 1 187 sw $sp,tl #save 3rd line pointer 188 189 subu $sp,$sp,$s6 # prepare stack to store the line 2 190 sw $sp,sl #save 2nd line pointer 191 192 subu $sp,$sp,$s6 # prepare stack to store the line 3 193 sw $sp,fl #save 1st line pointer 194 195 subu $sp,$sp,$s6 # prepare stack to store the result line 196 sw $sp,pl #save result (processing) line pointer 197 198 199 ## SYSCALL (read first line from source file) 200 li $v0, 14 # read-from-file service 201 move $a0, $s1 # show system file descriptor 202 lw $t0, fl 203 la $a1, 0($t0) # show system place for writing 204 move $a2, $s6 # limit is the line size 205 syscall # read whole line 206 207 ## SYSCALL (read second line from source file) 208 ## $t0 - place to write to next line 209 li $v0, 14 # read-from-file service 210 lw $t0, sl 211 la $a1, 0($t0) 212 syscall # read whole line 213 214 ## SYSCALL (read third line from source file) 215 li $v0, 14 # read-from-file service 216 lw $t0, tl 217 la $a1, 0($t0) 218 syscall # read whole line 219 ## $t0 - FREE 220 221 222 ## SYSCALL (write first line to file (it dosn't change anyway) 223 li $v0, 15 # write-to-file service 224 move $a0, $s5 # show system file descriptor 225 lw $t0, fl 226 la $a1, 0($t0) # show system place to read from 227 move $a2, $s6 # write a line size from showed pointer 228 syscall # write whole line 229 230 # Now there is place on stack for 4 lines 231 # 3 lines are loaded 232 # first line is already in target file 233 # There are adresses of begining of first, second, third & processing line in memory under fl,sl,th,pl 234 235 236################################################################################## 237## LOOPING THROUGH THE LINES 238################################################################################## 239 240 ## $s7 - loop marker for a while 241 move $s7, $s3 242 addu $s7, $s7, -3 #3 lines already loaded 243 244 # SYSCALL (printf info about begining of progressing) 245 li $v0,4 # print_string service 246 la $a0,processing # show adres to read from 247 syscall # printf(Processing..) 248 249 250p3l_loop: #process 3 lines loops 251 252 # SYSCALL (printf dot for every line you progress) 253 li $v0,4 # print_string service 254 la $a0,dot # show adress to read from 255 syscall # printf(.) 256 257################################################################################## 258## NOW 3 LINES ARE ON STACK (showed by fl,sl,tl) ACCTUAL PROCESSING HERE, LOOPING THROUGH BLOCKS IN LINE 259################################################################################## 260 261 li $t7, 1 # t7 is acctual pixel (from 1 to width-1) 262 addu $sp,$sp,-36 # make place on stack for brightness & pixel id 263 264prl: 265 266 # WRITE TO RESULT LINE FIRST AND LAST PIXEL (UGLY BUT PROBABLY BETTER THEN LOOP) 267 lw $t1, sl 268 lw $t2, pl 269 lb $t3, 0($t1) 270 sb $t3, 0($t2) 271 lb $t3, 1($t1) 272 sb $t3, 1($t2) 273 lb $t3, 2($t1) 274 sb $t3, 2($t2) 275 mul $t4,$s2,3 276 addu $t1, $t1, $t4 277 addu $t2, $t2, $t4 278 lb $t3, -3($t1) 279 sb $t3, -3($t2) 280 lb $t3, -2($t1) 281 sb $t3, -2($t2) 282 lb $t3, -1($t1) 283 sb $t3, -1($t2) 284 # WRITE TO RESULT LINE FIRST AND LAST PIXEL - END 285 286 # Loading brightness with ids of acctual block 287 beq $t7,$s2,prl_end 288 li $t9,0 289 lbl: 290 bge $t9,9,lbl_end # only ids 0-8 will be loaded 291 move $a0,$t9 # show the procedure id of pixel to load 292 jal take_pixel_b #call procedure, there is result in $a0 293 mul $t8,$t9,4 # calculete place on stack for becomed value 294 addu $t8,$t8,$sp 295 sw $a0, 0($t8) # store becomed pair id, brightness 296 addiu $t9,$t9,1 # progress next pixel in block 297 j lbl 298 lbl_end: 299 300 301 # Brightness with ids on stack now! sort and change center now. 302 303 # Sorting brightnesses with ids (quick buble) 304 li $t0,0 305 li $t9,1 306 sort: 307 beq $t0, 5, sort_end 308 beqz $t9, sort_end 309 li $t1,0 310 li $t9, 0 311 sort_in: 312 li $t8,8 313 subu $t8, $t8, $t0 314 beq $t1, $t8, sort_in_end 315 mul $t2,$t1,4 316 addu $t2, $sp, $t2 317 lh $t3, 0($t2) 318 lh $t4, 4($t2) 319 bge $t4,$t3,skip_swap 320 li $t9,1 321 lw $t3, 0($t2) 322 lw $t4, 4($t2) 323 sw $t4, 0($t2) 324 sw $t3, 4($t2) 325 skip_swap: 326 addiu $t1,$t1,1 327 j sort_in 328 sort_in_end: 329 addiu $t0,$t0,1 330 j sort 331 sort_end: 332 333 #brightness sorted here, just change pixel to valid value now 334 lw $a0, 16($sp) # show procedure id to take for writing (pair id, brightness in $a0 now) 335 srl $a0,$a0,16 #show procedure id to take for writing (only id in $a0 now) 336 jal write_pixel # call procedure - it will do rest of things needed 337 # now $t0 is valid pixel id 338 339 340 341 addiu $t7,$t7,1 # progress next block 342 j prl 343prl_end: 344 345 addu $sp,$sp,36 # free place on stack needed for brightnesses with ids 346 347 # Now whole line is processed and the result is on place showed by pl 348 349################################################################################## 350## Saving acctual line if it isnt end 351################################################################################## 352 353 beqz $s7, end_p3l_loop #when no more lines, end loop 354 355 ## SYSCALL (write line to file) 356 li $v0, 15 # write-to-file service 357 move $a0, $s5 # show system file descriptor 358 lw $t0, pl 359 la $a1, 0($t0) # show system place to read from 360 move $a2, $s6 # write a line size from showed pointer 361 syscall # write whole line (processed, with is next in order) 362 363 ## SYSCALL (read next line from source file) 364 li $v0, 14 # read-from-file service 365 move $a0, $s1 # show system file descriptor 366 lw $t0, fl 367 la $a1, 0($t0) # show system place for writing 368 move $a2, $s6 # limit is the line size 369 syscall # read whole line (next in order) 370 371 # swap fl,sl,tl (new order) 372 ## t0,$t1,$t2 - tmp value for swap 373 lw $t0,fl 374 lw $t1,sl 375 lw $t2,tl 376 sw $t1,fl 377 sw $t2,sl 378 sw $t0,tl 379 ## t0,$t1,$t2 - free 380 381 addiu $s7,$s7,-1 # process next line 382 j p3l_loop # } 383end_p3l_loop: 384 385 # Now all lines are processed and all without last 2 are saved in target file 386 387################################################################################## 388## Saving last two lines, free stack 389################################################################################## 390 391 ## SYSCALL (write line to file) 392 li $v0, 15 # write-to-file service 393 move $a0, $s5 # show system file descriptor 394 lw $t0, pl 395 la $a1, 0($t0) # show system place to read from 396 move $a2, $s6 # write a line size from showed pointer 397 syscall # write whole line 398 399 ## SYSCALL (write next line to result file) 400 li $v0, 15 # write-to-file service 401 lw $t0, tl 402 la $a1, 0($t0) 403 syscall # write whole line 404 405 ## $s7 - FREE 406 # free stack of line information 407 addu $sp,$sp,$s6 408 addu $sp,$sp,$s6 409 addu $sp,$sp,$s6 410 addu $sp,$sp,$s6 411 412 # Now all lines are saved and stack is free, its about the end 413 414 415exit: 416 ## SYSCALL (close source file) 417 li $v0, 16 # file-close service 418 la $a0, 0($s1) # show system source file descirptor 419 syscall # close fd1 (source file) 420 421 ## SYSCALL (close result file) 422 li $v0, 16 # file-close service 423 la $a0, 0($s5) # show system result file descriptor 424 syscall # close fd2 (result file) 425 426 ## SYSCALL (print exit msg) 427 li $v0, 4 # print_string 428 la $a0, thanks # show adress of end msg 429 syscall # print(thanks) 430 la $a0, new_filename # show adress of end msg param 431 syscall # print(thanks_param) 432 la $a0, newline # show adress of new line symbol 433 syscall # print(nl) 434 435 436 ## SYSCALL (end program) 437 li $v0, 10 438 syscall # exit program 439 440take_pixel_b: # calculate $a0 pixel in block brightness and save in $a0 with id on more imporant 4 bits, need $t7 (acctual block offset) & fl,sl,tl to be set 441 # now sl+t1*pixel_size is acctual block center 442 # where pixel_size is 3bytes (R,G,B) 443 ble $a0,2,rfl 444 ble $a0,5,rsl 445 446 #read from 3rd line 447 lw $t2, tl 448 addiu $t6,$a0,-6 449 j end_read 450 451 rsl: 452 #read from 2nd line 453 lw $t2, sl 454 addiu $t6,$a0,-3 455 j end_read 456 457 rfl: 458 #read from 1st line 459 lw $t2, fl 460 move $t6,$a0 461 462 end_read: 463 # now $t2 is begin of needed line counter 464 # and $t6 is pixel number in this line (with offset in $t0) 465 466 mul $t3, $t7, 3 467 mul $t6, $t6, 3 468 addiu $t3, $t3, -3 469 addu $t3, $t3, $t6 470 addu $t3, $t3, $t2 471 # now $t3 shows needed pixel adress 472 473 lb $t4,0($t3) 474 andi $t4,$t4,0x000000ff 475 lb $t5,1($t3) 476 andi $t5,$t5,0x000000ff 477 addu $t4,$t4,$t5 478 lb $t5,2($t3) 479 andi $t5,$t5,0x000000ff 480 addu $t4,$t4,$t5 481 # t4 is calculated brightness now 482 483 sll $a0,$a0,16 #make pair id brightness 484 addu $a0,$a0,$t4 #.. 485 486 jr $ra 487 488 489write_pixel: # write $a0 pixel to 4pixel in block, need $t7 (acctual block offset) & fl,sl,tl to be set 490 # now sl+t1*pixel_size is acctual block center 491 # where pixel_size is 3bytes (R,G,B) 492 ble $a0,2,rflw 493 ble $a0,5,rslw 494 495 #read from 3rd line 496 lw $t2, tl 497 addiu $t6,$a0,-6 498 j end_readw 499 500 rslw: 501 #read from 2nd line 502 lw $t2, sl 503 addiu $t6,$a0,-3 504 j end_readw 505 506 rflw: 507 #read from 1st line 508 lw $t2, fl 509 move $t6,$a0 510 511 end_readw: 512 # now $t2 is begin of needed line counter 513 # and $t6 is pixel number in this line (with offset in $t0) 514 515 mul $t3, $t7, 3 516 517 lw $t5,pl 518 addu $t5,$t5,$t3 519 520 mul $t6, $t6, 3 521 addiu $t3, $t3, -3 522 addu $t3, $t3, $t6 523 addu $t3, $t3, $t2 524 # now $t3 shows needed pixel adress 525 526 527 528 lb $t4,0($t3) 529 andi $t4,$t4,0x000000ff 530 sb $t4,0($t5) 531 532 #write new R 533 534 lb $t4,1($t3) 535 andi $t4,$t4,0x000000ff 536 sb $t4,1($t5) 537 538 #write new G 539 540 lb $t4,2($t3) 541 andi $t4,$t4,0x000000ff 542 sb $t4,2($t5) 543 544 #write new B 545 546 jr $ra