Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux x86 intel语法(NASM)中的条件跳转失败_Linux_Assembly_Nasm_Intel Syntax - Fatal编程技术网

linux x86 intel语法(NASM)中的条件跳转失败

linux x86 intel语法(NASM)中的条件跳转失败,linux,assembly,nasm,intel-syntax,Linux,Assembly,Nasm,Intel Syntax,故事(我是新手): 我开始阅读一本关于使用著名的nasm汇编程序在汇编(x86 intel)中编程的pdf教程,我在执行一个非常基本的汇编代码时遇到了一个问题(受教程中关于循环的代码启发) 问题(JE失败): 这个汇编代码应该从stdin中读取一个数字(一个字符(表示“0”+数字)),然后写入屏幕数字乘以“Hello world”\n。非常简单的循环:减少数字,如果数字等于零('0'不是整数,字符)跳转(je)到出口(mov eax,1\nT 0x80) 听起来很简单,但是当我尝试执行输出时,输

故事(我是新手): 我开始阅读一本关于使用著名的nasm汇编程序在汇编(x86 intel)中编程的pdf教程,我在执行一个非常基本的汇编代码时遇到了一个问题(受教程中关于循环的代码启发)

问题(JE失败): 这个汇编代码应该从stdin中读取一个数字(一个字符(表示“0”+数字)),然后写入屏幕数字乘以“Hello world”\n。非常简单的循环:减少数字,如果数字等于零('0'不是整数,字符)跳转(je)到出口(mov eax,1\nT 0x80)

听起来很简单,但是当我尝试执行输出时,输出很奇怪。(非常奇怪和大) 它在循环中运行多次,并在数字等于“0”时停止(奇怪的是,在程序停止之前,条件数字==“0”已被测试多次,并且应该为真)

实际上,我的问题是,当digit==“0”时,代码无法跳转

代码(很大)

segment .text
global _start
_start:

;Print 'Input a digit:'.
mov eax,4
mov ebx,1
mov ecx,msg1
mov edx,len1
int 0x80

;Input the digit.
mov eax,3
mov ebx,0
mov ecx,dig
mov edx,2
int 0x80

;Mov the first byte(the digit) in the ecx register.
;mov ecx,0
mov ecx,[dig]

;Use ecx to loop dig[0]-'0' times.
loop:

mov [dig],ecx

mov eax,4
mov ebx,1
mov ecx,dig
mov edx,1
int 0x80

mov eax,4
mov ebx,1
mov ecx,Hello
mov edx,Hellolen
int 0x80

;For some debuging (make the loop stop until return pressed)
;mov eax,3
;mov ebx,0
;mov ecx,some
;mov edx,2
;int 0x80

;Just move dig[0](some like character '4' or '7') to ecx register and compare ecx with character '0'.
mov ecx,[dig]
dec ecx
cmp ecx,'0'

;If comparison says ecx and '0' are equal jump to exit(to end the loop)
je exit

;If not jump back to loop
jmp loop

;Other stuff ...(like an exit procedure and a data(data,bss) segment)
exit:
mov eax,1
int 0x80

segment .data
msg1 db "Input a digit:"
len1 equ $-msg1

Hello db ":Hello world",0xa
Hellolen equ $-Hello

segment .bss
dig resb 2
some resb 2
输出

segment .text
global _start
_start:

;Print 'Input a digit:'.
mov eax,4
mov ebx,1
mov ecx,msg1
mov edx,len1
int 0x80

;Input the digit.
mov eax,3
mov ebx,0
mov ecx,dig
mov edx,2
int 0x80

;Mov the first byte(the digit) in the ecx register.
;mov ecx,0
mov ecx,[dig]

;Use ecx to loop dig[0]-'0' times.
loop:

mov [dig],ecx

mov eax,4
mov ebx,1
mov ecx,dig
mov edx,1
int 0x80

mov eax,4
mov ebx,1
mov ecx,Hello
mov edx,Hellolen
int 0x80

;For some debuging (make the loop stop until return pressed)
;mov eax,3
;mov ebx,0
;mov ecx,some
;mov edx,2
;int 0x80

;Just move dig[0](some like character '4' or '7') to ecx register and compare ecx with character '0'.
mov ecx,[dig]
dec ecx
cmp ecx,'0'

;If comparison says ecx and '0' are equal jump to exit(to end the loop)
je exit

;If not jump back to loop
jmp loop

;Other stuff ...(like an exit procedure and a data(data,bss) segment)
exit:
mov eax,1
int 0x80

segment .data
msg1 db "Input a digit:"
len1 equ $-msg1

Hello db ":Hello world",0xa
Hellolen equ $-Hello

segment .bss
dig resb 2
some resb 2
输入数字:4 4:你好,世界 3:你好,世界 2:你好,世界 1:你好,世界 0:你好,世界 ... …(后面有许多循环) ... 5:你好,世界 4:你好,世界 3:你好,世界 2:你好,世界 1:你好,世界 美元

这就是我的问题:这个代码有什么问题? 你能解释一下吗? 而且我不需要其他代码,它们会神奇地(没有解释)运行,因为我试图学习(我是个新手)


这就是我的问题(也是我在Stackoverflow.com上的第一个问题)

ECX
是32位的,一个字符只有8位。使用8位寄存器,例如
CL
而不是像jester提到的那样使用
ECX

,ECX是作为字符输入的,因此您可能应该使用CL

loop:
  mov [dig],cl
  ...
  mov cl,[dig]
  dec cl
  cmp cl,'0'
  jne loop
您还可以使用movzx加载ecx,movzx将清除寄存器的顶部位(即零扩展加载):


请注意,通常建议不要使用al、bl、cl、dl寄存器,因为它们的使用没有得到充分优化。我不知道这是否仍然是真的。

非常感谢。还有别的办法只是好奇吗?总有别的办法;)例如,您甚至不需要将其加载到寄存器中,您可以将其保留在内存中并执行
dec byte[dig];cmp byte[dig],“0”
。我在教程中找不到任何movz。我搜索并发现“movz指令将src操作数复制到dest操作数中,并将src未提供的剩余位用零(0)填充。”。如果是小端或大端,这会产生什么影响?因为在两个相同的位位置中,都将被正确填充?movz首先加载1,2或4字节(在x86上),然后清除其他位。因此,“z”不会影响数据的结尾(即不会加载高位字节)。英特尔语法助记符是
movzx
,而不是
movz
。在
字节
大小说明符之后没有