因此,我需要在 arm asm 中撰寫一個程式,該程式將打開一個目錄并列印出每個條目的 ino_d、d_type 和 d_name 值。我正在使用函式 opendir 來執行此操作。但是,當我運行以下代碼時(請注意,我不會一次運行所有測驗,這些只是我在程式的幾次單獨運行中嘗試使用 x0 做的事情)
ldr x0, =dirname //dirname = ".\0"
bl opendir
// and try this as a test (Bus error)
mov x0, xzr
// or try this as a test (__GI__readdir64)
ldr x0, =output // output = "%-20llu 0xx %s\n\0"
// or try this (seg fault)
ldr w1, [x0]
總是有一些錯誤導致程式崩潰。像分段錯誤,或“__GI__readdir64 (dirp=0x1)”錯誤,或總線錯誤。
有誰知道(或者可以給我一個關于去哪里解決這個問題的提示)發生了什么?
更新:我要運行這個程式,我用 gcc 編譯它,并使用 qemu-system-aarch64 在 aarch64 vm 下運行它。
// command in terminal
gcc -g -o "main.s" "main.out"
./main.out
完整的代碼,以防它幫助任何有更多背景關系的人
.global main
.align 2
.extern printf
.extern strcpy
.extern opendir
.extern closedir
.extern readdir
.extern perror
.extern __errno_location
.text
.equ _ino_d, 0
.equ _off_d, 8
.equ _d_reclen, 16
.equ _d_type, 18
.equ _d_name, 19
main:
stp x29, x30, [sp, -16]!
stp x20, x21, [sp, -16]!
mov w20, w0
mov x21, x1
cmp w20, 1
beq 2f
// set dirname to passed in arg if any was given from the command line
1:
// I don't know how to do the equivelent of
// dirname = argv[1]
// so I'm copying argv[1] into dirname
ldr x0, =dirname
ldr x1, [x21, 8]
bl strcpy
// point to jump to if no args were passed in
2:
// this is the part of the code the bug is originating in
ldr x0, =dirname
bl opendir
ldr x0, =output
// this is the part of the code the bug is originating in
printLoop:
// load de with proper dirent struct
mov x0, x20
bl readdir
cbz x0, errCheck
// loads the format text and d_ino member
mov x7, x0
ldr x0, =output
ldr x1, [x7]
// loads the d_typ member
add x7, x7, _d_type
ldrb w2, [x7]
// loads the dname member
add x7, x7, #1
ldrb w3, [x7]
bl printf
b printLoop
errCheck:
// prints out an error message if something went wrong with reading the directory
bl __errno_location
ldr w1, [x0]
cbz w1, closeDir
ldr x0, =errmsg
bl perror
closeDir:
mov x0, x20
bl closedir
// checks if errno was 0 or not. and stores 1 in retval if errno wasn't 0
bl __errno_location
ldr w1, [x0]
cbz w1, retIsZero
mov w1, #1
str w1, [x0]
b 5f
retIsZero:
str xzr, [x0]
b 5f
4:
// prints error message if error occured
ldr x0, =dirname
bl perror
5:
// cleanup and return retval
ldp x20, x21, [sp], 16
ldp x29, x30, [sp], 16
ldr x0, =ret_val
ldr w0, [x0]
ret
.data
output: .asciz "%-20llu 0xx %s\n"
test_output: .asciz "%d\n"
dirname: .asciz "."
errmsg: .asciz "readdir() failed"
ret_val: .word 1
.end
更新:當在 gdb 之外運行代碼時,只是列印出來以跟蹤程式在導致錯誤之前的位置,似乎下面的代碼部分是問題所在
printLoop:
// load de with proper dirent struct
mov x0, x20
bl readdir
// seems I'm calling readdir wrongly or something
// involving readdir
更新:所以看起來我得到奇怪錯誤的原因是因為在呼叫 opendir 之后,null 存盤在 x0. 當我用 null 呼叫 readdir 時,它會導致崩潰
uj5u.com熱心網友回復:
我弄清楚我做錯了什么。我沒有從 opendir 保存目錄資料(將指標放在 x0 中),然后我呼叫了 readdir(然后將 dirent 放在 x0 中)。并且由于我沒有備份 DIR* 表單 opendir 它導致崩潰
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430130.html
上一篇:Mips用整數和字符制作字串
下一篇:Intel64andIA-32ArchitecturesSoftwareDeveloper'sManual對OUT指令的描述是否包含錯誤?