📄 risc8_asm.pl
字号:
}
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 + -