You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用cmp指令比较高数值时汇编程序异常的原因排查

问题描述

我期望程序先在控制台多次打印*行,再打印一行=,随后暂停并打印pause,之后重复该流程。但实际程序每次都会触发jg c3指令,导致每次sleep后直接打印pause并重复。不过将cmp word [counter], 0xF000改为cmp word [counter], 0xF时,程序可正常运行。请问这是什么原因?

汇编代码
global Start
extern _GetStdHandle@4
extern _WriteFile@20
extern Sleep

STD_OUTPUT_HANDLE equ -11
STD_INPUT_HANDLE equ -10
NULL equ 0

section .data
counter dw 0

section .bss

section .text

Start:
    mov ebp, esp
    sub esp, 4
    ; hStdOut = GetstdHandle ( STD_OUTPUT_HANDLE)
Cont:
    push STD_OUTPUT_HANDLE
    call _GetStdHandle@4
    mov ebx, eax
    mov word [counter],0
write:
    inc word [counter]
    push 0
    lea eax, [ebp-4]
    push eax
    cmp word [counter], 0xF000
    je c2
    jg c3
c1:
    push (character_end-character)
    push character
    jmp do_write
c2:
    push (character2_end-character2)
    push character2
    jmp do_write
c3:
    push (character3_end-character3)
    push character3
    mov word [counter],0
    push 0x0F;0x5FF0
    call Sleep
    jmp do_write
do_write:
    push ebx
    call _WriteFile@20
start_again:
    jmp write
character:
    db '************************************************************************',0x0D,0x0A,NULL
character_end:
character2:
    db '=========================================================================',0x0D,0x0A,NULL
character2_end:
character3:
    db 'Pause',0x0D,0x0A,NULL
character3_end:
问题原因

核心问题出在数据类型的符号解读上:

  • counter是16位的word类型,CPU对它的比较会遵循带符号整数规则。
  • 0xF000作为16位带符号数,对应的十进制是-4096,是负数。而你的counter从0开始自增,每次都是正整数,任何正整数都比负数大,所以第一次执行cmp后,jg(带符号大于跳转)的条件直接满足,直接跳去执行c3的暂停和打印pause逻辑。
  • 当你把比较值改成0xF(十进制15)时,这是一个正的16位整数,counter从1自增到15时都满足小于等于的条件,正常走c1打印*;等于15时跳转到c2打印=;下一次自增到16,16>15触发jg c3,逻辑就符合预期了。

内容的提问来源于stack exchange,提问作者VCD_WL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:17:14