x64 NASM汇编64位jle条件跳转不符合预期执行问题排查
问题定位与修复
核心错误
循环终止判断的汇编指令存在逻辑错误:
cmp QWORD [_i], number
这里的number是BSS段变量的内存地址(如你调试中的0x40404c),而非变量存储的用户输入值。实际执行时是把_i的数值(比如4)和number的地址做比较,显然4远小于该地址,因此jle _loop会始终触发跳转,导致循环无法终止。
修复方案
将比较指令修改为直接读取number变量的数值,而非地址:
cmp QWORD [_i], QWORD [number]
这样才是正确比较_i和number两个变量存储的数值,当_i大于用户输入的number值时,循环会正常退出。
额外修正点
原代码中printf调用的参数顺序不符合x64 Linux调用约定:printf的第一个参数应为格式串,第二个是输出内容,原代码顺序颠倒会导致输出异常,已一并修正。
完整修正代码
; Nasm v 2.15.05 (on Linux x64) extern printf extern scanf true EQU 0x1 false EQU 0x0 section .data notificationString DB "num: ", 0x0 notificationStringFormat DB "%s", 0x0 ; %s\0 userInputFormat DB "%d", 0x0 ; %d\0 resultPrintFormat DB "%d", 0xA, 0x0 ; %d\n\0 section .bss number RESB 0x8 _i RESB 0x8 section .text global main ; validate if the given number(RDI) is a prime number isPrimeNumber: mov r10, 0x2 ; looping variable _inspect: mov rax, rdi cdq mov rbx, r10 div rbx cmp rdx, 0x0 je _itIsNotPrime jne _notDetermined _itIsNotPrime: mov rax, false retn _notDetermined: inc r10 mov r9, r10 cmp r9, rdi je _itIsPrime jne _inspect _itIsPrime: mov rax, true retn main: push rbp mov rbp, rsp mov rdi, notificationStringFormat mov rsi, notificationString call printf mov rdi, userInputFormat mov rsi, number call scanf mov QWORD [_i], 0x2 _loop: mov rdi, [_i] call isPrimeNumber cmp rax, true je _primeTrue jne _primeFalse _primeTrue: mov rdi, resultPrintFormat mov rsi, [_i] call printf jmp _primeEnd _primeFalse: nop _primeEnd: add QWORD [_i], 0x1 cmp QWORD [_i], QWORD [number] ; 核心修复点 jle _loop _loop_end: mov rsp, rbp pop rbp retn
内容的提问来源于stack exchange,提问作者KnightChaser
相关产品推荐
相关产品推荐

