1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690
|
listing:
mov edx,[input_file]
call open
jc input_not_found
call load_file
mov [input],eax
cmp ecx,38h
jb invalid_input
cmp dword [eax],1A736166h
jne invalid_input
cmp dword [eax+44],0
je incomplete_input
add [eax+16],eax
add [eax+24],eax
add [eax+32],eax
add [eax+40],eax
add [eax+48],eax
mov edx,[eax+16]
add [eax+8],edx
add [eax+12],edx
mov edx,[eax+12]
call open
jc code_not_found
call load_file
mov [assembled_code],eax
mov [assembled_code_length],ecx
call close
mov [maximum_address_length],0
mov ebx,[input]
mov esi,[ebx+40]
lea ebp,[esi-4]
add ebp,[ebx+44]
get_offsets_for_lines:
cmp esi,ebp
je offsets_prepared
mov edx,[esi+4]
add edx,[ebx+32]
find_line_loaded_from_source:
test byte [edx+7],1 shl 7
jz store_offset_in_line
mov edx,[edx+8]
add edx,[ebx+32]
jmp find_line_loaded_from_source
store_offset_in_line:
cmp dword [edx+12],0
jne get_next_offset
mov [edx+12],esi
movzx ecx,byte [esi+27]
and cl,1
mov edi,[esi+20]
test edi,edi
jz base_name_length_ok
xor ecx,ecx
btr edi,31
jc count_base_name_characters
dec edi
shl edi,2
add edi,[ebx+48]
mov edi,[edi]
count_base_name_characters:
mov ecx,[ebx+20]
sub ecx,edi
add edi,[ebx+16]
mov edx,edi
xor al,al
repne scasb
mov ecx,edi
sub ecx,edx
base_name_length_ok:
cmp byte [esi+18],1
jb first_register_length_ok
ja first_register_with_scale
add ecx,5
jmp first_register_length_ok
first_register_with_scale:
add ecx,5+3
first_register_length_ok:
cmp byte [esi+19],1
jb second_register_length_ok
ja second_register_with_scale
add ecx,5
jmp second_register_length_ok
second_register_with_scale:
add ecx,5+3
second_register_length_ok:
cmp ecx,[maximum_address_length]
jb get_next_offset
mov [maximum_address_length],ecx
get_next_offset:
add esi,28
jmp get_offsets_for_lines
offsets_prepared:
mov eax,[esi]
mov [code_end],eax
add [maximum_address_length],19
mov edi,characters
xor al,al
make_characters_table:
stosb
inc al
jnz make_characters_table
mov edi,characters
mov esi,symbol_characters+1
movzx ecx,byte [esi-1]
xor eax,eax
mark_symbol_characters:
lodsb
mov byte [edi+eax],0
loop mark_symbol_characters
mov eax,[code_bytes_per_line]
imul eax,3
add eax,[maximum_address_length]
add eax,18
call alloc
jc not_enough_memory
mov [output_buffer],eax
mov esi,[ebx+32]
mov ebp,esi
add ebp,[ebx+36]
mov edx,[output_file]
call create
jc writing_error
mov [output_handle],ebx
xor eax,eax
mov [current_source_file],eax
mov [last_listed_address],eax
mov [code_length],eax
generate_listing:
cmp esi,ebp
jae listing_done
mov edi,[output_buffer]
test byte [esi+7],1 shl 7
jnz next_line
mov ebx,[esi+12]
test ebx,ebx
jz no_code_listing
test byte [ebx+26],11b
jnz no_code_listing
push esi
mov edx,[esi]
mov ecx,[esi+4]
find_next_code_point:
add esi,16
call skip_preprocessed_line
cmp esi,ebp
je last_code_point
cmp edx,[esi]
jne next_line_ok
cmp ecx,[esi+4]
je find_next_code_point
next_line_ok:
test byte [esi+7],1 shl 7
jnz find_next_code_point
mov eax,[esi+12]
test eax,eax
jz find_next_code_point
test byte [eax+26],11b
jnz find_next_code_point
mov eax,[eax]
jmp calculate_code_length
last_code_point:
mov eax,[code_end]
calculate_code_length:
pop esi
mov edx,[ebx]
sub eax,edx
jz no_code_listing
mov [code_length],eax
mov [code_offset],edx
add eax,edx
cmp eax,[assembled_code_length]
jbe write_file_offset
mov [code_length],0
write_file_offset:
call write_hex_dword
mov ax,': '
stosw
call list_address
call list_code
jmp code_listing_ok
no_code_listing:
mov al,20h
mov ecx,8+2
rep stosb
call list_address
mov ecx,[code_bytes_per_line]
imul ecx,3
mov al,20h
rep stosb
code_listing_ok:
call write_listing_data
mov eax,[input]
mov edx,[esi]
test edx,edx
jz main_source_file
add edx,[eax+32]
jmp source_name_ok
main_source_file:
mov edx,[eax+8]
source_name_ok:
cmp edx,[current_source_file]
je source_loaded
push ebx
push edx
call open
jc source_not_found
pop eax
xchg eax,[current_source_file]
test eax,eax
jz load_source
mov eax,[source]
call free
load_source:
call load_file
mov [source],eax
mov [source_length],ecx
call close
pop ebx
source_loaded:
mov eax,[source]
add eax,[esi+8]
mov [current_source_line],eax
push esi ebp
call write_source_line
pop ebp esi
write_supplemental_rows:
mov eax,[code_length]
or eax,[current_source_line]
jz next_line
mov edi,[output_buffer]
mov ecx,8+2
movzx eax,[show_addresses]
imul eax,[maximum_address_length]
add ecx,eax
mov al,20h
rep stosb
call list_code
call write_listing_data
push esi ebp
call write_source_line
pop ebp esi
jmp write_supplemental_rows
next_line:
mov edx,[esi]
mov ecx,[esi+4]
find_next_line:
add esi,16
call skip_preprocessed_line
cmp edx,[esi]
jne generate_listing
cmp ecx,[esi+4]
jne generate_listing
jmp find_next_line
list_address:
cmp [show_addresses],0
je address_ok
mov [address_start],edi
mov eax,[esi+12]
test eax,eax
jz address_finished
cmp [last_listed_address],0
je make_address
push esi edi
lea esi,[eax+8]
mov edi,[last_listed_address]
mov ecx,17
repe cmpsb
pop edi esi
je address_finished
make_address:
mov ebx,[esi+12]
lea eax,[ebx+8]
mov [last_listed_address],eax
mov al,'['
stosb
mov edx,[ebx+20]
test edx,edx
jz write_main_address
push esi
mov esi,edx
mov eax,[input]
btr esi,31
jc base_name_ready
dec esi
shl esi,2
add esi,[eax+48]
mov esi,[esi]
base_name_ready:
add esi,[eax+16]
copy_section_name:
lodsb
test al,al
jz section_name_ok
stosb
jmp copy_section_name
section_name_ok:
pop esi
mov al,':'
test edx,80000000h
jz address_separator_ok
cmp byte [ebx+27],0
jne address_separator_ok
mov al,'+'
address_separator_ok:
stosb
write_main_address:
cmp byte [ebx+27],0
jne write_negative_address
mov edx,[ebx+8+4]
call write_hex_dword
mov edx,[ebx+8]
call write_hex_dword
jmp write_address_registers
write_negative_address:
mov al,'-'
stosb
mov eax,[ebx+8]
mov edx,[ebx+8+4]
not eax
not edx
add eax,1
adc edx,0
push eax
call write_hex_dword
pop edx
call write_hex_dword
write_address_registers:
mov dl,[ebx+16]
mov dh,[ebx+18]
call address_register
mov dl,[ebx+17]
mov dh,[ebx+19]
call address_register
mov ax,']'
stosb
address_finished:
mov ecx,[maximum_address_length]
sub ecx,edi
add ecx,[address_start]
mov al,20h
rep stosb
address_ok:
ret
address_register:
cmp dh,0
je register_ok
jl negative_register
mov al,'+'
jmp register_sign_ok
negative_register:
mov al,'-'
register_sign_ok:
stosb
push esi
mov esi,address_registers
find_register:
lodsb
test al,al
jz register_found
cmp al,dl
je register_found
cmp dl,[esi]
je register_found
lodsb
movzx eax,al
add esi,eax
jmp find_register
register_found:
lodsb
movzx ecx,al
rep movsb
pop esi
cmp dh,1
je register_ok
mov al,'*'
stosb
test dh,0F0h
jz first_scale_digit_ok
mov al,dh
shr al,4
cmp al,10
sbb al,69h
das
stosb
first_scale_digit_ok:
mov al,dh
and al,1111b
cmp al,10
sbb al,69h
das
stosb
register_ok:
ret
list_code:
mov ecx,[code_length]
cmp ecx,[code_bytes_per_line]
jb code_bytes_count_ready
mov ecx,[code_bytes_per_line]
code_bytes_count_ready:
sub [code_length],ecx
mov edx,[code_offset]
add [code_offset],ecx
jecxz code_bytes_ok
push ecx
add edx,[assembled_code]
list_code_bytes:
mov al,[edx]
and al,1111b
cmp al,10
sbb al,69h
das
mov ah,al
mov al,[edx]
shr al,4
cmp al,10
sbb al,69h
das
stosw
mov al,20h
stosb
inc edx
loop list_code_bytes
pop ecx
code_bytes_ok:
neg ecx
add ecx,[code_bytes_per_line]
imul ecx,3
mov al,20h
rep stosb
ret
write_listing_data:
mov ecx,[output_buffer]
sub ecx,edi
and ecx,111b
mov al,20h
rep stosb
mov edx,[output_buffer]
mov ecx,edi
sub ecx,edx
mov ebx,[output_handle]
call write
jc writing_error
ret
write_source_line:
mov esi,[current_source_line]
test esi,esi
je write_line_break
mov ebp,[source_length]
add ebp,[source]
mov ebx,characters
xor cl,cl
start_cutting:
xor dl,dl
cut_source_line:
cmp esi,ebp
je end_of_file
lodsb
cmp al,0Dh
je cr_character
cmp al,0Ah
je lf_character
cmp al,1Ah
je end_of_line
or al,al
jz end_of_line
cmp dl,3Bh
je cut_source_line
cmp al,3Bh
je start_special_block
cmp dl,22h
je inside_string
cmp dl,27h
je inside_string
cmp al,'\'
je check_for_line_continuation
xlatb
test al,al
jz start_cutting
cmp dl,0FFh
je cut_source_line
cmp al,22h
je start_special_block
cmp al,27h
je start_special_block
mov dl,0FFh
jmp cut_source_line
start_special_block:
mov dl,al
jmp cut_source_line
inside_string:
cmp al,dl
jne cut_source_line
jmp start_cutting
check_for_line_continuation:
or cl,0FFh
cmp esi,ebp
je end_of_file
mov al,[esi]
cmp al,20h
je start_cutting
cmp al,0Dh
je start_cutting
cmp al,0Ah
je start_cutting
cmp al,3Bh
je start_cutting
xor cl,cl
jmp start_cutting
cr_character:
mov edx,esi
mov word [line_break],0Dh
cmp esi,ebp
je line_with_break
mov al,[esi]
cmp al,0Ah
jne line_with_break
inc edx
mov [line_break+1],al
jmp line_with_break
lf_character:
mov edx,esi
mov word [line_break],0Ah
cmp esi,ebp
je line_with_break
mov al,[esi]
cmp al,0Dh
jne line_with_break
inc edx
mov [line_break+1],al
line_with_break:
dec esi
jmp write_line
end_of_line:
dec esi
end_of_file:
mov edx,esi
write_line:
cmp cl,0FFh
je continued_line
xor edx,edx
continued_line:
xchg edx,[current_source_line]
mov ecx,esi
sub ecx,edx
mov ebx,[output_handle]
call write
jc writing_error
write_line_break:
mov edx,line_break
mov ecx,2
cmp [line_break+1],0
jne line_break_size_ok
dec ecx
line_break_size_ok:
call write
jc writing_error
ret
listing_done:
mov ebx,[output_handle]
call close
ret
load_file:
push ebx
mov al,2
xor edx,edx
call lseek
test eax,eax
jz empty_file
push eax
call alloc
jc not_enough_memory
push eax
xor al,al
xor edx,edx
call lseek
mov ecx,[esp+4]
mov edx,[esp]
call read
jc reading_error
pop eax ecx
pop ebx
ret
empty_file:
pop ebx
mov ecx,eax
ret
write_hex_dword:
mov ecx,8
write_hex_digits:
xor al,al
shld eax,edx,4
cmp al,10
sbb al,69h
das
stosb
shl edx,4
loop write_hex_digits
ret
skip_preprocessed_line:
lods byte [esi]
cmp al,1Ah
je skip_preprocessed_symbol
cmp al,3Bh
je skip_preprocessed_symbol
cmp al,22h
je skip_preprocessed_string
or al,al
jnz skip_preprocessed_line
ret
skip_preprocessed_symbol:
lods byte [esi]
movzx eax,al
add esi,eax
jmp skip_preprocessed_line
skip_preprocessed_string:
lods dword [esi]
add esi,eax
jmp skip_preprocessed_line
not_enough_memory:
call error
db 'not enough memory to load the required data',0
input_not_found:
call error
db 'the input file was not found',0
code_not_found:
call error
db 'the assembled file was not found',0
source_not_found:
call error
db 'could not find some of the source files',0
reading_error:
call error
db 'some error occured while trying to read file',0
writing_error:
call error
db 'some error occured while trying to write file',0
invalid_input:
call error
db 'input file is not a recognized assembly information format',0
incomplete_input:
call error
db 'input file does not contain an assembly dump',0
symbol_characters db 27, 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'
address_registers db 23h,2,'bx'
db 25h,2,'bp'
db 26h,2,'si'
db 27h,2,'di'
db 40h,3,'eax'
db 41h,3,'ecx'
db 42h,3,'edx'
db 43h,3,'ebx'
db 44h,3,'esp'
db 45h,3,'ebp'
db 46h,3,'esi'
db 47h,3,'edi'
db 48h,3,'r8d'
db 49h,3,'r9d'
db 4Ah,4,'r10d'
db 4Bh,4,'r11d'
db 4Ch,4,'r12d'
db 4Dh,4,'r13d'
db 4Eh,4,'r14d'
db 4Fh,4,'r15d'
db 80h,3,'rax'
db 81h,3,'rcx'
db 82h,3,'rdx'
db 83h,3,'rbx'
db 84h,3,'rsp'
db 85h,3,'rbp'
db 86h,3,'rsi'
db 87h,3,'rdi'
db 88h,2,'r8'
db 89h,2,'r9'
db 8Ah,3,'r10'
db 8Bh,3,'r11'
db 8Ch,3,'r12'
db 8Dh,3,'r13'
db 8Eh,3,'r14'
db 8Fh,3,'r15'
db 0F4h,3,'eip'
db 0F8h,3,'rip'
db 0,1,'?'
|