问题
Here's my assembly code and my main subroutine. Here are my macros and constants:
.text
fmt: .string "x \t\t ln(x)\n"
sfmt: .string "%.10lf \t %.10lf\n"
error: .string "Error"
filename: .string "input.bin"
.data
LIM: .double 0r1.0E-13
zero: .double 0r0.0
one: .double 0r1.0
half: .double 0r0.5
define(i_r,w19)
define(j_r,w20)
define(n_r,w21)
define(fd_r,w22)
define(ln_x,d8)
define(cur_term,d24)
define(n_read,x25)
define(x_j,d26)
BUF_SIZE = 98*8
AT_FDCWD = -100
O_RDONLY = 0
buf_s = 16
.bss
x_arr: .skip BUF_SIZE
fp .req x29
lr .req x30
.balign 4
.global main
Here's my main subroutine:
main:
stp fp,lr,[sp,-16]!
mov fp,sp
ldp fp,lr,[sp],16
ret
I already used gdb however, it only points out that the SIGSEGV signal came from 0x0000000000420358 in main(). How can I narrow down where in 'main' this signal comes from? P.S I only know the basics of GDB.
GDB Stuff:(update)
(gdb) x/i $pc
=> 0x420358: .inst 0x00000000 ; undefined
I don't know if this helps but this is the C version THAT WORKS. I am converting it to assembly because thats what I need to hand in. Also we cannot use any types of converter since thats considered cheating.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> //Used for the keyword for flags and other predefined values for the argument on openat,etc.
#define LIM 1.0e-13
#define DOUBSIZE 100 //There are 97 double values in the binary file
#define buf_size 98*8
double x[DOUBSIZE];
int main() {
register int i = 1,j = 0,fd = openat(AT_FDCWD,"input.bin",O_RDONLY); //int fd = openat(int dirfd,const char *pathname (basically a string),int flags,mode_t mode);
register double ln_x = 0.0,cur_term;
//double *x; //(only local variable) //(a local variable so it must be in the stack)only assuming there are 32 double precision values in the binary file
register long n_read = read(fd,&x,buf_size); //reads in 8 bytes(lost the double x[...] in this line since x is now pointing at the buffer
if(fd == -1) {
printf("Error!");
return 0;
}
if(n_read == -1) { //Error checker
printf("Error!");
return 0;
}
printf("x \t\t ln(x)\n"); //The header of the thing to be printed
while(j < (buf_size/8)) { //note that it is implied that EOF = -1 in C
if(x[j] <= 0.5) { //if x is less than or equal to 1/2,go to the next double value(assuming I don't know values in the bin file)
j++;
i = 1;
continue;
}
cur_term = (1.0/i) * (pow((double)((x[j]-1.0)/(x[j])),i));
ln_x += cur_term;
while(cur_term >= LIM) { //continue to accumulate terms until the absolute value of the term is less than 1.0E-13
i++; //follows the pattern of the series.
cur_term = (1.0/i)*(pow((double)((x[j]-1.0)/(x[j])),i)); //since it should start with x[1]
ln_x += cur_term; //adds the new term to previous ln(x) value
}
printf("%.10lf \t %.10lf\n",x[j],ln_x); //prints the current value of ln(x) and x
j++; //manages which x double value will be used next
i = 1;
ln_x = 0.0;
}
close(fd);
return 0;
}
回答1:
Turns out your main
is in the .bss
section, not .text
where it belongs, so it can only contain all-zero bytes. (And it won't be executable).
GDB normally only wants to disassemble code in the .text
section so that also explains GDB being weird.
This is why you should reduce your code to a MCVE (Minimal / complete / verifiable example) to make it as small as possible while still containing the problem.
来源:https://stackoverflow.com/questions/59200557/what-gdb-commands-should-i-use-to-narrow-down-where-in-label-main-did-i-get-th