执行除以10,我得到了一个"浮点异常"。当在GDB中单步执行代码时,我发现除除时ax = 23,bx = 10。
.686 ;
;
BSS SEGMENT ;
BUF DB 0 ;
BSS ENDS ;
;
DATA SEGMENT ;
ASSUME DS:BSS ;
;
PUBLIC _start ;
_start PROC ;
MOV cx, 230 ;
CALL prN ;
;
...
_start ENDP ;
;
;---------------------------------------;
; prNum ;
; TOFIX: numbers are printed backwards ;
;---------------------------------------;
; CX = number to print ;
;---------------------------------------;
prN PROC ;
MOV ax, cx ; prepare first loop
MOV bx, 10 ; !! BX = 10
@@loop: ;
;- PROBLEMATIC LINE vvvvvvvvvvvvvvvv;
DIV bx ; Get rightmost decimal digit
;- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;
ADD dl, '0' ; convert to ASCII-numeral
MOV BYTE PTR [BUF], dl ;
PUSHA ; Not ideal, this is a playground
;- print byte buffer ;
...
;-- ;
POPA ;
OR ax, ax ; Is cx = 0?
JNZ @@loop ; NO: loop for the next decimal part
RET ; YES: leave loop
prN ENDP ;
DATA ENDS
END
循环的示例(如我所想象的):
MOV ax, cx ; ax = 230
MOV bx, 10 ; bx = 10
;
(@@loop) ;
DIX bx ; ax = 23 - dx = 0
;- print ; STDOUT = 0
OR ax, ax ; ZF = 0
JNZ @@loop ; continue looping with AX = 23
DIV bx ; AX = 2 - DX = 3 --> THIS is where the SIGFPE occurs
;- print ; STDOUT = 03
OR ax, ax ; ZF = 0
JNZ @@loop ; continue looping with AX = 2
;
DIX bx ; AX = 0 - DX = 2
;- print ; STOUD = 032 (230 but backwards)
OR ax, ax ; ZF = 1
JNZ @@loop ; not looping
RET ; all done, we are returning
由于我是用23除以10,所以我希望这个运算不会有问题,特别是:
- 不被零除
- 无溢流
- 无下溢
我希望
AX = 2
DX = 3
BX = 10
1条答案
按热度按时间ggazkfy81#
我疏忽了。16位
DIV
操作接收DX:AX。由于DX在第一遍中为0x0030,所以我所除的数似乎不再有效:
0x00300017除以10大于0xFFFF。
https://c9x.me/x86/html/file_module_x86_id_72.html