📄 risc8_asm_pl.txt
字号:
} elsif($word[$start] eq "dcb") { # dcb if($word[$start+1] =~ /^\"/) { @stringg = split "\"", $line_org; @bytes = unpack ("C*", $stringg[1]); for($i=0; $i <= $#bytes; $i = $i+1) { printf TMP_F ("byte=%x\n", $bytes[$i]); #printf ("%x\n", $bytes[$i]); $address = $address + 1; } } else { for($i=$start+1; $i <= $#word; $i = $i+1) { ($status, $off) = extract_byte($word[$i]); printf TMP_F ("byte=%x\n", $off); $address = $address + 1; } } } elsif($word[$start] eq "dmem") { # dmem check_argument_count($#word, 1); if($word[$start+1] !~ /\(/) { $count = $word[$start+1]; $fill = "00";} else { @filler = split /\(/, $word[$start+1]; $count = $filler[0]; $fill = $filler[1]; $fill =~ s/\)//g; } ($status, $fill) = extract_byte($fill); ($status, $off) = extract_word($count); if($status != 0) { printf ("invalid dmem count\n");} else { for($i=0; $i < $off; $i = $i + 1) { printf TMP_F ("byte=%x\n", $fill); $address = $address + 1; } } } } #--------------------------------------------- # Type 11: pmov - Pseudo MOV instruction #--------------------------------------------- elsif($opcode_type{$word[$start]} == 11) { check_argument_count($#word, ($start+2)); if($word[$start+1] !~ /^(a0|a1|a2|a3)$/) { # pmov An 16-bit printf("Error: Invalid pmove argument \"%s\" at line %d: %s\n", $word[$start+2], $line_no, $line_o); $error = $error + 1; } else { $opcode = $opcode_value{"ldi"} . $reg_map{$word[$start+1]}. "0"; printf TMP_F ("pmov=%s", $opcode); $opcode = $opcode_value{"ldi"} . $reg_map{$word[$start+1]}. "1"; printf TMP_F ("#6#%s", $opcode); ($status, $off) = extract_word($word[$start+2]); if($status == 0) { printf TMP_F ("#7#%x\n", $off);} elsif($status == 2) { printf TMP_F ("#8#%s#9#%d#a#%d\n", $off,$line_no, ($address + 2));} $address = $address + 4; } } } #---------------------------------------------------------- # Second pass to Resolve the forward references # Create the memory file - 16 bytes per line #---------------------------------------------------------- $error2 = 0; $byte_count = 0; if($error == 0) { close TMP_F; open (TMP_F, "$tmp_file") or die ("Can't open $tmp_file: $!\n"); while ($line = <TMP_F>) { chop $line; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} if($line =~ /@(.+)/) { printf MEM_F ("\n@%s\n", $1); $byte_count = 0;} elsif($line =~ /opcode=(\d{4})(\d{4})$/) { printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2}); $byte_count++; } elsif($line =~ /byte=(.{1})$/) { printf MEM_F (" 0%s", $1); $byte_count++;} elsif($line =~ /byte=(.{2})$/) { printf MEM_F (" %s", $1); $byte_count++;} elsif($line =~ /word=(.+)$/) { @digits = split "", $1; if($#digits == 0 ) { $low = "0" . $digits[0]; $high = "00";} elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";} elsif($#digits == 2) { $low = $digits[1] . $digits[2] ; $high = "0" . $digits[0];} else { $low = $digits[2] . $digits[3] ; $high = $digits[0] . $digits[1];} printf MEM_F (" %s", $low); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $high); $byte_count++; } elsif($line =~ /pmov=(\d{4})(\d{4})#6#(\d{4})(\d{4})#7#(.+)$/) { @digits = split "", $5; if($#digits == 0 ) { $low = "0" . $digits[0]; $high = "00";} elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";} elsif($#digits == 2) { $low = $digits[1] . $digits[2] ; $high = "0" . $digits[0];} else { $low = $digits[2] . $digits[3] ; $high = $digits[0] . $digits[1];} printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2}); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $low); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s%s", $bin2_hex{$3}, $bin2_hex{$4}); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $high); $byte_count++; } elsif($line =~ /pmov=(\d{4})(\d{4})#6#(\d{4})(\d{4})#8#(.+)#9#(.+)#a#(.+)$/) { if($valid_label{$5} == 1) { $off1 = $addr_label{$5}; $offset = ""; $offset = sprintf "%lx", $off1; @digits = split "", $offset; if($#digits == 0 ) { $low = "0" . $digits[0]; $high = "00";} elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";} elsif($#digits == 2) { $low = $digits[1] . $digits[2] ; $high = "0" . $digits[0];} else { $low = $digits[2] . $digits[3] ; $high = $digits[0] . $digits[1];} printf MEM_F (" %s%s", $bin2_hex{$1}, $bin2_hex{$2}); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $low); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s%s", $bin2_hex{$3}, $bin2_hex{$4}); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $high); $byte_count++; } else { $error2 = $error2 + 1; printf("Error: Label not found \"%s\" at line %d\n", $5, $6); next; } } elsif($line =~ /b_label=(.+)#4#(.+)#5#(.+)$/) { if($valid_label{$1} == 1) { #printf("LAB=%d, %d\n", $addr_label{$1}, $3); $off1 = ($addr_label{$1}-$3); $offset = ""; $offset = sprintf "%lx", $off1; if($off1 > 255) { $error2 = $error2 + 1; printf("Error: relative jump bigger than 8bits \"%s\" on line %d\n", $1, $2); } else { #printf MEM_F ("lab = %d, %s\n", $off1, $offset); if($off1 <= 15) { printf MEM_F (" 0%s", $offset); } else { printf MEM_F (" %s", $offset); } $byte_count++; } } else { $error2 = $error2 + 1; printf("Error: Label not found \"%s\" at line %d\n", $1, $2); next; } } elsif($line =~ /w_label=(.+)#4#(.+)#5#(.+)$/) { if($valid_label{$1} == 1) { $off1 = $addr_label{$1}; $offset = ""; $offset = sprintf "%lx", $off1; @digits = split "", $offset; if($#digits == 0 ) { $low = "0" . $digits[0]; $high = "00";} elsif($#digits == 1) { $low = $digits[0] . $digits[1] ; $high = "00";} elsif($#digits == 2) { $low = $digits[1] . $digits[2] ; $high = "0" . $digits[0];} else { $low = $digits[2] . $digits[3] ; $high = $digits[0] . $digits[1];} printf MEM_F (" %s", $low); $byte_count++; if($byte_count == 16) { printf MEM_F ("\n"); $byte_count = 0;} printf MEM_F (" %s", $high); $byte_count++; } else { $error2 = $error2 + 1; printf("Error: Label not found \"%s\" at line %d\n", $1, $2); next; } } } printf MEM_F ("\n"); } close ASM_F; close MEM_F; close TMP_F; #close LST_F; # generate the hex file open (MEM_F, "$mem_file") or die ("Can't open $mem_file: $!\n"); for($i=0 ; $i <= 65535; $i = $i+1) { $hex_data[$i] = $mem_init_value;} $address = 0; while ($line = <MEM_F>) { #chop $line; @words = split " ", $line; if($words[0] =~ /^@(.+)$/) {$addr = "0x" . $1; $address = oct $addr;} elsif($#words == -1) {next;} else{ for($i=0 ; $i <= $#words; $i = $i+1) { $hex_data[$address] = $words[$i]; $address = $address + 1;} } } $count = 0; for($i=0 ; $i <= 65535; $i = $i+1) { if($count == 32) { printf HEX_F ("\n"); $count = 0; } printf HEX_F ("%s", $hex_data[$i]); $count = $count + 1; } printf HEX_F ("\n"); close MEM_F; close HEX_F; system ("rm $tmp_file"); $t_errors = $error+$error2; printf("\nTotal Errors = %d\n", $t_errors); if($t_errors != 0) { #system("rm $hex_file"); system("rm $mem_file"); } #---------------------------------------------------------- # End of main Program and start of procedure declarations #---------------------------------------------------------- #------------------------------------------------------------- # Checks for valid number of arguments in an instruction #------------------------------------------------------------- sub check_argument_count { my ($tmp1, $tmp2) = @_; if($tmp1 != $tmp2) { printf("Error: Invalid number of arguments at line %d: %s\n", $line_no, $line_o); $error = $error + 1; } } #------------------------------------------------------------- # Checks for valid data register usage in an instruction #------------------------------------------------------------- sub check_data_register { my ($tmp) = @_; if($tmp !~ /^(r0|r1|r2|r3|r4|r5|r6|r7)$/) { printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } #------------------------------------------------------------- # Checks for valid address register usage in an instruction #------------------------------------------------------------- sub check_address_register { my ($tmp) = @_; if($tmp !~ /^(a0|a1|a2|a3)$/) { printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } #------------------------------------------------------------- # Checks for valid conditions in a jump instruction #------------------------------------------------------------- sub check_condition { my ($tmp) = @_; if($tmp !~ /^(eq|ne|gt|lt|cs|cc|ns|al)$/) { printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } #------------------------------------------------------------- # Checks for valid register arguments in a mov instruction #------------------------------------------------------------- sub check_mov_registers { my ($tmp) = @_; if($tmp !~ /^(sp|a0|a1|a2|a3|r0|r1|r2|r3|r4|r5|r6|r7)$/) { printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } #------------------------------------------------------------- # Extracts the 8-bit immediate data #------------------------------------------------------------- sub extract_byte { my ($tmp) = @_; if($tmp =~ /^(0x.+)$/) {$tmp = oct $1; if($tmp <= 255) {return (0,$tmp);} else { printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; return (1,$tmp); } } elsif ($tmp =~ /^(\d+)$/) { $tmp = $1; if($tmp <= 255) {return (0, $tmp);} else { printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; return (1,$tmp); } } elsif ($valid_label{$tmp}) { #elsif ($valid_label{$tmp} == 1) { $tmp1 = $address + 1 - $addr_label{$tmp}; $tmp = 0xff - $tmp1 + 1; #printf("addr=%x label=%x %x\n", $address, $tmp1, $tmp); if($tmp1 <= 255) {return (0, $tmp);} else { printf("Error: Overflow, 8-bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; return (1,$tmp); } } else { return (2,$tmp); } } #------------------------------------------------------------- # Extracts the 16-bit immediate data #------------------------------------------------------------- sub extract_word { my ($tmp) = @_; if($tmp =~ /^(0x.+)$/) {$tmp = oct $1; if($tmp <= 0xffff) {return (0, $tmp);} else { printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; return (1,$tmp); } } elsif ($tmp =~ /^(\d+)$/) {$tmp = $1; if($tmp <= 0xffff) {return (0, $tmp);} else { printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; return (1,$tmp); } } elsif ($valid_label{$tmp}) { $tmp = $addr_label{$tmp}; #elsif ($valid_label{$tmp} == 1) { $tmp = $addr_label{$tmp}; return (0, $tmp); } else { return (2,$tmp); } } #------------------------------------------------------------- # Extracts the address for the "org" directive #------------------------------------------------------------- sub extract_addr { my ($tmp) = @_; if($tmp =~ /^(0x.+)$/) {$tmp = oct $1; if($tmp <= 0xffff) {return $tmp;} else { printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } elsif ($tmp =~ /^(\d+)$/) { $tmp = $1; if($tmp <= 0xffff) {return $tmp;} else { printf("Error: Overflow, 16bit value expected \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } } else { printf("Error: Invalid argument \"%s\" at line %d: %s\n", $tmp, $line_no, $line_o); $error = $error + 1; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -