intel汇编中.IF指令为什么会使程序出错

一个程序渣渣的小后院 2016-10-20 11:35:50
其中sort_arr是SDWORD类型数组
edi存的是索引计数
arrTypeSize = type sort_arr

实现的是冒泡排序内层循环交换的部分,结果这样会报错
0x000720E4 处(位于 sort.exe 中)引发的异常: 0xC0000005: 写入位置 0x470751A4 时发生访问冲突。


mov ebx, sort_arr[edi * arrTypeSize]
mov val, ebx
mov ebx, sort_arr[edi * arrTypeSize + arrTypeSize]
mov val_next, ebx

.IF val > ebx
mov sort_arr[edi * arrTypeSize], ebx
mov ebx, val
mov sort_arr[edi * arrTypeSize + arrTypeSize], ebx
.ENDIF


看反汇编代码的时候从.ENDIF进入的时候是这样的,IF内的内存对应的代码都是???

然后出错之后反汇编代码变成这样。

最后我在.ENDIF前面随便加一语句如NOP或者MOV EBX, 0后就不会出现异常了 请问是什么原因呢
...全文
292 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
32位软件在64位系统中是可以运行的

greatak 2019-09-30
  • 打赏
  • 举报
回复
引用 12 楼 一个程序渣渣的小后院 的回复:
[quote=引用 11 楼 早打大打打核战争的回复:]啊。确实有你说的问题。VC++ 2015中的ml 14.0汇编后的转移位置有问题,而且把inc edi这条指令吃掉了。 这是ml 14汇编出的程序: 这是ml 12(VC++ 2013中带的)汇编出的程序:
多半是编译器的问题了,谢谢![/quote] 这是什么软件?TASM?win7 64bit 如何使用?
  • 打赏
  • 举报
回复
引用 11 楼 早打大打打核战争的回复:
啊。确实有你说的问题。VC++ 2015中的ml 14.0汇编后的转移位置有问题,而且把inc edi这条指令吃掉了。
这是ml 14汇编出的程序:

这是ml 12(VC++ 2013中带的)汇编出的程序:
多半是编译器的问题了,谢谢!
  • 打赏
  • 举报
回复
啊。确实有你说的问题。VC++ 2015中的ml 14.0汇编后的转移位置有问题,而且把inc edi这条指令吃掉了。
这是ml 14汇编出的程序:

这是ml 12(VC++ 2013中带的)汇编出的程序:

  • 打赏
  • 举报
回复
看这个吧 上面那个有可能运行不了

TITLE MASM Template						(main.asm)
;..........................................
; Author	:	Roc_King-Seven
; Purpose	:	This program is to realise Bubble sort
; Data		:	2016/09/27
; Update	:	2016/10/20
;..........................................


.686P		; Pentium Pro or later
.MODEL flat, stdcall
.STACK 4096
option casemap:none		;大小写不敏感


Crlf PROTO
DumpRegs PROTO
printf          PROTO C :ptr byte,:vararg
scanf           PROTO C :dword,:vararg
gets		PROTO C :ptr byte
getchar		PROTO C
ExitProcess	PROTO,dwExitCode:DWORD	  	; exit program

INCLUDELIB C:\Irvine\USER32.LIB
INCLUDELIB C:\Irvine\KERNEL32.LIB
INCLUDELIB C:\Irvine\MSVCRT.LIB
INCLUDELIB C:\Irvine\IRVINE32.LIB


exit equ <INVOKE ExitProcess,0>

chr$ MACRO any_text:VARARG
        LOCAL txtname
        .data
          IFDEF __UNICODE__
            WSTR txtname,any_text
            align 4
            .code
            EXITM <OFFSET txtname>
          ENDIF

          txtname db any_text,0
          align 4
        .code
          EXITM <OFFSET txtname>
ENDM

arrTypeSize = TYPE SDWORD  
.data?
	n SDWORD ?
	val SDWORD ?
	val_next SDWORD ?
	eax_cpy SDWORD ?
	sort_arr SDWORD 100 DUP(?)

.code
	main PROC

	invoke printf, chr$("请输入数组元素的个数1~100: ")
	invoke scanf, chr$("%d"),offset n
	invoke getchar
	invoke printf, chr$("请按顺序输入所有元素: ")

	mov ecx, n
	lea esi, sort_arr
	.WHILE ecx != 0
		push ecx
		invoke scanf, chr$("%d"), esi
		invoke getchar
		pop ecx
		add esi, arrTypeSize
		dec ecx
	.ENDW

	mov esi, n
	xor eax, eax	
	.WHILE esi != 0
		mov ebx, n
		sub ebx, eax
		lea ecx, [ebx-1]
		xor edi, edi
		.WHILE ecx != 0
			mov ebx, sort_arr[edi * arrTypeSize]
			mov val, ebx	
			mov ebx, sort_arr[edi * arrTypeSize + arrTypeSize]
			mov val_next, ebx
;##############################################problem
			.IF val > ebx
			mov sort_arr[edi * arrTypeSize], ebx
			mov ebx, val
			mov sort_arr[edi * arrTypeSize + arrTypeSize], ebx	
			NOP
			.ENDIF
;#######################################################
			inc edi
			dec ecx
		.ENDW

		inc eax
		dec esi
	.ENDW

	invoke printf, chr$("排序后的结果为: ")

	xor edi, edi
	mov ecx, n
	.WHILE ecx != 0
		mov eax, sort_arr[edi * arrTypeSize]
		push ecx
		invoke printf, chr$("%d "),eax
		pop ecx
		inc edi	
		dec ecx
	.ENDW

	invoke printf, chr$(0dh,0ah,"BubbleSort Finished!")
	invoke getchar
	exit

main ENDP
END main
  • 打赏
  • 举报
回复

TITLE MASM Template						(main.asm)
;..........................................
; Author	:	Roc_King-Seven
; Purpose	:	This program is to realise Bubble sort
; Data		:	2016/09/27
; Update	:	2016/10/20
;..........................................


.686P		; Pentium Pro or later
.MODEL flat, stdcall
.STACK 4096
option casemap:none		;´óСд²»Ãô¸Ð


Crlf PROTO
DumpRegs PROTO
printf          PROTO C :ptr byte,:vararg
scanf           PROTO C :dword,:vararg
gets		PROTO C :ptr byte
getchar		PROTO C
ExitProcess	PROTO,dwExitCode:DWORD	  	; exit program

INCLUDELIB C:\Irvine\USER32.LIB
INCLUDELIB C:\Irvine\KERNEL32.LIB
INCLUDELIB C:\Irvine\MSVCRT.LIB
INCLUDELIB C:\Irvine\IRVINE32.LIB


exit equ <INVOKE ExitProcess,0>

chr$ MACRO any_text:VARARG
        LOCAL txtname
        .data
          IFDEF __UNICODE__
            WSTR txtname,any_text
            align 4
            .code
            EXITM <OFFSET txtname>
          ENDIF

          txtname db any_text,0
          align 4
        .code
          EXITM <OFFSET txtname>
ENDM

arrTypeSize = TYPE SDWORD  
.data?
	n SDWORD ?
	val SDWORD ?
	val_next SDWORD ?
	eax_cpy SDWORD ?
	sort_arr SDWORD 100 DUP(?)

.code
	main PROC

	invoke printf, chr$("ÇëÊäÈëÊý×éÔªËصĸöÊý1~100: ")
	invoke scanf, chr$("%d"),offset n
	invoke getchar
	invoke printf, chr$("Ç밴˳ÐòÊäÈëËùÓÐÔªËØ: ")

	mov ecx, n
	lea esi, sort_arr
	.WHILE ecx != 0
		push ecx
		invoke scanf, chr$("%d"), esi
		invoke getchar
		pop ecx
		add esi, arrTypeSize
		dec ecx
	.ENDW

	mov esi, n
	xor eax, eax	
	.WHILE esi != 0
		mov ebx, n
		sub ebx, eax
		lea ecx, [ebx-1]
		xor edi, edi
		.WHILE ecx != 0
			mov ebx, sort_arr[edi * arrTypeSize]
			mov val, ebx	
			mov ebx, sort_arr[edi * arrTypeSize + arrTypeSize]
			mov val_next, ebx
;################################################problem
			.IF val > ebx
			mov sort_arr[edi * arrTypeSize], ebx
			mov ebx, val
			mov sort_arr[edi * arrTypeSize + arrTypeSize], ebx	
			NOP
			.ENDIF
###############################################################
			inc edi
			dec ecx
		.ENDW

		inc eax
		dec esi
	.ENDW

	invoke printf, chr$("ÅÅÐòºóµÄ½á¹ûΪ: ")

	xor edi, edi
	mov ecx, n
	.WHILE ecx != 0
		mov eax, sort_arr[edi * arrTypeSize]
		push ecx
		invoke printf, chr$("%d "),eax
		pop ecx
		inc edi	
		dec ecx
	.ENDW

	invoke printf, chr$(0dh,0ah,"BubbleSort Finished!")
	invoke getchar
	exit

main ENDP
END main
  • 打赏
  • 举报
回复
引用 2 楼 zara的回复:
不应该啊?不过,你第二图上,并没有 .ENDIF 语句,反而有个 .ENDW 是不是配对上出错了,看 .IF 语句生成的 jl 指令的目标地址也不对,0E120EA 是0E120E4 处 mov 指令的中间啊?用个什么编译器,换个呢?可以的话,完整代码放上来看看?
我也是有这个疑问,跳转的地方并不在指令语句的地址处。 那个.ENDW是冒泡排序内层循环的结束符。 我觉得.ENDIF我觉得不用生成反汇编吧因为.IF被编译成CMP和JMP,我现在贴代码上来
zara 2016-10-21
  • 打赏
  • 举报
回复
不应该啊?不过,你第二图上,并没有 .ENDIF 语句,反而有个 .ENDW 是不是配对上出错了,看 .IF 语句生成的 jl 指令的目标地址也不对,0E120EA 是0E120E4 处 mov 指令的中间啊?用个什么编译器,换个呢?可以的话,完整代码放上来看看?
  • 打赏
  • 举报
回复
引用 9 楼 早打大打打核战争的回复:
我用VC 2015中的 Microsoft (R) Macro Assembler Version 14.00.24210.0 汇编你的程序是没有问题的。
把NOP去掉呢,还是可以运行吗
  • 打赏
  • 举报
回复
我用VC 2015中的 Microsoft (R) Macro Assembler Version 14.00.24210.0 汇编你的程序是没有问题的。
  • 打赏
  • 举报
回复
引用 7 楼 zara的回复:
难不成是vs2015的问题 老师也说2013的可以运行…
zara 2016-10-21
  • 打赏
  • 举报
回复
zara 2016-10-21
  • 打赏
  • 举报
回复
用 masm32 试了有无添加 nop 指令两个情况,生成的代码跳转指令都是正确地指向了后面的 inc edi 指令:
[imgtp://img.my.csdn.net/uploads/201610/21/1477025340_7872.png[/img]
  • 打赏
  • 举报
回复
而且我用CMP指令重写这段代码也可以正常运行,请问是.IF是有什么需要注意的地方还是我这个代码有问题啊

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧