2016-12-28 2 views
0

Duntemann의 책 (제 3 판)을 읽고 방금 x86 어셈블리를 배우기 시작했습니다. Fedora 23 (64 비트)의 변형을 사용하고 있습니다. 다음은 코드입니다 :왜 AF와 SF가 설정되지 않습니까?

sandbox: sandbox.o 
    ld -o sandbox sandbox.o -melf_i386 
sandbox.o: sandbox.asm 
    nasm -f elf -g -F stabs sandbox.asm -l sandbox.lst 

그래서 당신은 내가 32 비트 실행 파일이 아닌 64 비트를 조립하는 치료를 촬영했습니다 볼 수 있습니다 : 다음과 같이

section .data 
section .text 
    global _start 
_start: 
    nop 
; Put your experiments between the two nops... 
    mov eax,0FFFFFFFFh 
    mov ebx,02Dh 
    dec ebx 
    inc eax 
; Put your experiments between the two nops... 
    nop 

내 메이크입니다. 그러나 문제는 dec ebx 명령 이전에 책이 주장한 것과 반대로 AFSF 플래그가 설정되어 있지 않다는 것입니다. insight에서 프로그램을 실행하면 32 비트 레지스터가 표시되어 실행 파일이 32 비트임을 더욱 확실하게 알 수 있습니다. 다음은 gdb으로 표시되는 상태이며 dec ebx 명령 직전의 상태입니다. 대학원 (217)에

(gdb) info reg 
eax   0xffffffff -1 
ecx   0x0 0 
edx   0x0 0 
ebx   0x2d 45 
esp   0xffffce80 0xffffce80 
ebp   0x0 0x0 
esi   0x0 0 
edi   0x0 0 
eip   0x804806b 0x804806b <_start+11> 
eflags   0x202 [ IF ] 
cs    0x23 35 
ss    0x2b 43 
ds    0x2b 43 
es    0x2b 43 
fs    0x0 0 
gs    0x0 0 

Duntemann의 버전은 AFSF 플래그가 설정되어 있는지 보여줍니다. 내 코드에 어떤 문제가 있습니까?

+3

'mov'는 플래그를 설정하지 않습니다. 구글이 "intel manual 2"에 대한 영향을받는 지시와 플래그가있는 공식 문서 –

답변

5

Margaret Bloom이 (논평 한대로) mov 명령어는 이 아니며 플래그를 설정했습니다. 실제로 플래그에는 아무런 영향을 미치지 않으므로 플래그의 현재 상태를 손상시키지 않고 레지스터 또는 메모리의 내용을 설정하려는 경우에 매우 유용합니다.

이 내용은 the official Intel IA-32 ISA reference manual에 문서화되어 있지만, 나 같은 사람이라면 게으르다. 운 좋게도 운이 좋습니다. 몇몇 종류의 사람들은 자신의 웹 사이트에 공식 문서의 일부를 올렸으며, 단순히 "Goolling"이라는 x86과 명령어 니모닉의 이름으로 쉽게 찾을 수 있습니다. 예를 들어, "x86 mov"에 대한 최고의 결과는 this page입니다.
없음 영향을받지

플래그 : 다음 절을합니다.

기타 안내에는 물론 다른 것들이 있습니다. add 명령어는 실질적으로 모든 플래그를 설정합니다 (here 참조).

그래서 코드를 살펴보면 무의미한 가비지 값으로 설정된 플래그로 실행이 시작됩니다. 기술적으로, 그들은 마지막으로 설정 한 값을 포함 할 것이지만, 프로그램의 맥락에서 의미가 없습니다. 왜냐하면 그것들을 아무 것도 설정하지 않았기 때문에, 의미있는 값으로 설정되는 것에 의존 할 수 없기 때문입니다!

지침 nopmov도 플래그 값에 영향을주지 않으므로 가비지 값이 계속 포함됩니다.

플래그는 dec 명령이 실행될 때까지 의미있는 값을 포함하지 않습니다. 그런 다음 the documentation에 따라 오 v 플로우, 부호, 제로, 조정 W 패리티 플래그가 감소 조작의 결과에 따라 설정됩니다. 캐리 플래그는 dec의 영향을받지 않으므로 가비지 값을 계속 포함합니다.

inc instructiondec과 똑같은 방식으로 플래그를 설정하므로 오버플로, 부호, 0, 조정 및 패리티 플래그가 변경되지만 캐리 플래그는 변경되지 않고 가비지 값을 계속 포함합니다.


본인이 참조하는 책의 복사본이 없으므로 실제로 말한 내용을 알지 못합니다. 코드 실행 중 해당 시점에 레지스터/플래그 상태의 덤프를 표시하는 경우 플래그는 가비지 값이며 중요하지 않으므로 레지스터의 값이 다음과 같이 어떻게 변경되었는지에 초점을 맞추어야합니다. mov 명령어의 결과 사실 mov 명령어가 플래그를 설정한다는 것을 암시하는 것이라면 책에 버그가 있습니다. :-)

+0

깃발이 쓰레기 값을 가질 수 있는지조차 몰랐다. 그리고 예, 저자는 AF와 SF 깃발이 처음에 설정된 이유에 대해 아무 말도하지 않았습니다. 더 놀랍게도 나는 지구의 AF 플래그가 어떻게 설정 될지 이해할 수 없었다. –

+2

음, 그들은 당신에게 쓰레기입니다. 너의 것보다 먼저 실행 된 코드는 모두 쓰레기라고 생각하지 않을 것이다. 실제로 지시 사항을 쓰레기로 설정하지는 않습니다. –

관련 문제