arcgistif没有值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了arcgistif没有值相关的知识,希望对你有一定的参考价值。
arcgistif没有值,需要在arcgis中把这个值重新设置为null即可,这样arcgis就会识别他自己的NoData,同时导入.tif格式文件和中国地区shp文件: 打开以表格显示分区统计,不过无论待分类栅格数据时int还是float类型重分类都不能赋值小数,这是arcgis本身问题。解决方法是对其要分类的所有数值乘上一个常数。 参考技术A arcgistif没有值,是因为对于文件的一些参数和路径如果设置不正确的话是没有输出的一个值的,还有对于文件的一些内容没有正确或者出现bug也是会没有值输出的如果函数没有明确使用'ret',为啥没有返回值
【中文标题】如果函数没有明确使用\'ret\',为啥没有返回值【英文标题】:Why is no value returned if a function does not explicity use 'ret'如果函数没有明确使用'ret',为什么没有返回值 【发布时间】:2013-12-14 00:10:56 【问题描述】:我有以下程序:
SECTION .text
main:
mov ebx, 10
mov ecx, 50
repeat:
inc ebx
loop repeat
mov eax, ebx
ret
当这个程序运行时,它按预期返回 60。但是,如果您删除最后的 ret
语句,程序运行正常,但随后返回 0。这是为什么呢?
【问题讨论】:
你怎么知道它“运行良好”? 【参考方案1】:当您离开“ret”时,计算机会执行最后一个“move eax, ebx”,然后执行计算机内存中发生的任何事情。
我很惊讶您没有收到非法指令/访问;这将是最常见的反应。不知何故,垃圾指令在破坏寄存器之后就像返回一样。
“返回 60”是什么意思也有点不清楚。你的意思是作为命令提示符的值?很明显,您的程序无法防御非法指令陷阱。 我不清楚当你遇到这样一个没有防御的陷阱时 Windows 会做什么。我从经验中知道,当我这样做时,Windows 往往会终止我的进程,并且我会得到一些随机退出状态。 “0”可能就是这样的状态。
尝试添加:
mov byte ptr[eax], 0
在“ret”指令之前;这将导致非法的内存引用。你报告你得到什么状态。如果您在这种情况下得到零状态结果,我不会感到惊讶。
【讨论】:
OP 显然很幸运,链接器在main
之后放置的任何函数都返回零。 main
进入代码 (.text
) 段,以及通过与标准运行时链接获得的运行时样板启动函数。我希望另一个函数会跟随它,而不是数据。请记住这是main
,而不是_start
。
很明显他的意思是main的返回值,其中的低8位最终作为Unix进程退出状态。既然您问了,以SIGSEGV
终止的Unix 进程的退出状态为139。(分段违规=非法内存访问)。 SIGSEGV = 信号 11,并且 139 = 128+11。 ***.com/a/1104641/224132。希望这有助于解释当他让 main 失败时 OP 看到了什么。【参考方案2】:
因为它通过并运行链接器放在它之后的下一个函数。
请参阅我关于 Ira 的答案的 cmets,了解为什么您的代码不会崩溃。如果您没有与 C 运行时库启动代码链接(即您只有 _start
而不是 main
),则执行将遇到一些非代码,并且非法指令出错,或者尝试访问未映射的内存。见下文。
反汇编你的最终二进制文件,看看发生了什么。当我尝试这个时,我发现链接器将main
放在标准C 运行时启动函数frame_dummy
和__libc_csu_init
之间。它
00000000004004f6 <main>:
4004f6: b8 0a 00 00 00 mov $0xa,%eax
4004fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
0000000000400500 <__libc_csu_init>:
400500: 41 57 push %r15
400502: 41 56 push %r14
400504: 41 89 ff mov %edi,%r15d
400507: 41 55 push %r13
... a bunch more code that eventually returns.
您可能已经发现使用调试器、单步指令会发生什么。
顺便说一句,如果您确实使用gcc -static -nostartfiles
或通过自己组装(as foo.s
)/链接(ld foo.o
)制作了一个独立的二进制文件,您将获得一个包含您的一条指令的 888 字节文件,其中剩下的是 ELF 标头和东西。
$ cat > fallthrough.s <<EOF
.globl main
main:
.globl _start
_start:
mov $10, %eax
# fall through
EOF
$ gcc -g -static -nostartfiles fallthrough.s -o fallthrough
$ gdb fallthrough
(gdb) b _start # breakpoint
(gdb) r # run the prog
(gdb) disassemble /r _start, _start+40
Dump of assembler code from 0x4000d4 to 0x4000fc:
=> 0x00000000004000d4 <main+0>: b8 0a 00 00 00 mov $0xa,%eax
0x00000000004000d9: 00 00 add %al,(%rax)
0x00000000004000db: 00 00 add %al,(%rax)
0x00000000004000dd: 00 00 add %al,(%rax)
0x00000000004000df: 00 2c 00 add %ch,(%rax,%rax,1)
0x00000000004000e2: 00 00 add %al,(%rax)
0x00000000004000e4: 02 00 add (%rax),%al
0x00000000004000e6: 00 00 add %al,(%rax)
0x00000000004000e8: 00 00 add %al,(%rax)
0x00000000004000ea: 08 00 or %al,(%rax)
0x00000000004000ec: 00 00 add %al,(%rax)
0x00000000004000ee: 00 00 add %al,(%rax)
0x00000000004000f0: d4 (bad)
0x00000000004000f1: 00 40 00 add %al,0x0(%rax)
...
(gdb) layout asm #text-window mode. layout reg is great for single-stepping, BTW.
(gdb) si # step instruction
0x00000000004000d9 in ?? ()
(gdb) si
Program received signal SIGSEGV, Segmentation fault.
0x00000000004000d9 in ?? ()
(gdb) c
Continuing.
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
内存中代码后面的00
字节也存在于 ELF 可执行文件中。文件的内存映射仅发生在页面粒度上,因此最终都映射为可执行指令。 (机器代码不会从可执行文件的磁盘缓存中复制出来;内存只是以读取+执行权限映射到execve(2)
s 二进制文件的进程中。)
$ objdump -s a.out
a.out: file format elf64-x86-64
Contents of section .note.gnu.build-id:
4000b0 04000000 14000000 03000000 474e5500 ............GNU.
4000c0 db31c97d 55481b9a 57110753 1786dd1a .1.UH..W..S....
4000d0 11679958 .g.X
Contents of section .text:
4000d4 b80a0000 00 .....
Contents of section .debug_aranges:
0000 2c000000 02000000 00000800 00000000 ,...............
0010 d4004000 00000000 05000000 00000000 ..@.............
0020 00000000 00000000 00000000 00000000 ................
...
$ size a.out
text data bss dec hex filename
41 0 0 41 29 a.out
剥离二进制文件仍然会导致段错误,但使用不同的指令。好吗?
# b _start would be b *0x4000d4 without symbols.
(gdb) r
...
Program received signal SIGSEGV, Segmentation fault.
0x00000000004000d9 in ?? ()
(gdb) disassemble /r $rip-5, $rip +15
Dump of assembler code from 0x4000d4 to 0x4000e8:
0x00000000004000d4: b8 0a 00 00 00 mov $0xa,%eax
=> 0x00000000004000d9: 00 2e add %ch,(%rsi)
0x00000000004000db: 73 68 jae 0x400145
0x00000000004000dd: 73 74 jae 0x400153
0x00000000004000df: 72 74 jb 0x400155
0x00000000004000e1: 61 (bad)
0x00000000004000e2: 62 (bad)
0x00000000004000e3: 00 2e add %ch,(%rsi)
0x00000000004000e5: 6e outsb %ds:(%rsi),(%dx)
0x00000000004000e6: 6f outsl %ds:(%rsi),(%dx)
0x00000000004000e7: 74 65 je 0x40014e
$ hexdump -C a.out
...
000000d0 11 67 99 58 b8 0a 00 00 00 00 2e 73 68 73 74 72 |.g.X.......shstr|
000000e0 74 61 62 00 2e 6e 6f 74 65 2e 67 6e 75 2e 62 75 |tab..note.gnu.bu|
000000f0 69 6c 64 2d 69 64 00 2e 74 65 78 74 00 00 00 00 |ild-id..text....|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
我们的 mov
指令是我从 hexdump 中包含的第一行中的 b8 0a 00 00 00
。我认为下面的00 2e ...
是一个 ELF 数据结构,可能是部分的索引或其他东西。作为 x86 指令,它是一个 add %ch,(%rsi)
,它会出现段错误,因为 %rsi
没有指向可写内存。 (ABI 说除了堆栈指针之外的寄存器在进程入口时未定义,但 Linux 选择在 ELF 加载器中将它们归零以避免泄漏内核数据。%rsi
不指向可写内存,进程可能不指向有。)
那么,如果您在此处添加退货呢?不,没有什么可以返回到。堆栈包含指向进程 args 环境变量的指针。您必须进行exit
系统调用。
.section .text
.globl _start
_start:
xor %edi, %edi
mov $231, %eax # exit(0)
syscall
# movl $1, %eax # The 32bit ABI works even for processes in long mode, BTW.
# int $0x80 # exit(edx)
【讨论】:
哇,我写这篇文章的时间比我打算的要长得多。 >. "那么执行会命中一个"命中一个什么? ;) @Michael:谢谢。我刚刚结束了我的漫无边际,并没有真正校对后意识到我可能已经写了一个多小时,关于一个愚蠢的老问题。以上是关于arcgistif没有值的主要内容,如果未能解决你的问题,请参考以下文章