鱼C论坛

 找回密码
 立即注册
查看: 5060|回复: 15

[已解决]还是一个有问题的程序,请指点一下

[复制链接]
发表于 2021-5-25 15:31:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 肖-肖 于 2021-5-25 15:37 编辑

题目是:
       实现:在270H开始的内存单元中存放了16个8位带符号数,找出其中最大和最小的数分别存入以280H和282H为首地址的内存单元
我的代码是:
DATAS SEGMENT
    ;此处输入数据段代码
    org 0270H
    n db 81H,70H,82H,76H,84H,74H,83H,78H,88H,71H,85H,73H,75H,86H,76H,87H          
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    mov si,0270H
    mov al,[si]
    mov bl,al
    mov cl,0FH
 ks:inc si
    dec cl
    jz over
    cmp al,[si]
    JLE next
    mov al,[si]
next:cmp bl,[si]
        JG ks
        mov bl,[si]
        jmp ks
over:mov si,0280H
        mov [si],bl
        add si,2
        mov [si],al         
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
我运行出来的结果是:
问3.png
我觉得如果看成是带符号数得话,88H不才是最小的那个负数吗? 我哪里不对?请指点一下,详细点(最好给个代码),我比较笨,谢谢了
最佳答案
2021-5-25 19:05:45
79 是最大,79 + 1 = 80
80 是最小
80 < 88

你的数据里面没有 80,最小是 81
没有 79,最大是 78

另一个问题,边界错误
试试这个代码,最后一个数据是 80,最小
DATAS SEGMENT
    ;此处输入数据段代码
    org 0270H
    n db 81H,70H,82H,76H,84H,74H,83H,78H,88H,71H,85H,73H,75H,86H,76H,80H
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    mov si,0270H
    mov al,[si]
    mov bl,al
    mov cl,0FH
    ;mov cl,10H
ks: inc si
    dec cl
    jz over
    cmp al,[si]
    JLE next
    mov al,[si]
next:cmp bl,[si]
    JG ks
    mov bl,[si]
    jmp ks
over:mov si,0280H
    mov [si],bl
    add si,2
    mov [si],al
    MOV AH,4CH
    INT 21H
CODES ENDS
END START
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-5-25 16:12:32 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 16:19:33 | 显示全部楼层


哦哦 您的意思是说:这么cmp相当于减,这个我知道,但是后边的那个表格说它之影响:ZF和CF对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 16:21:24 | 显示全部楼层
肖-肖 发表于 2021-5-25 16:19
哦哦 您的意思是说:这么cmp相当于减,这个我知道,但是后边的那个表格说它之影响:ZF和CF对吗?

恩,是的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 16:22:05 | 显示全部楼层

不对吧
我查了下资料
资料如下
CMP比较指令使用寄存器Rn的值减去operand2的值,根据操作的结果影响新CPSR中相应的条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。CMP指令与SUBS指令的区别在于CMP指令不保存运算结果。在进行两个数据大小判断时,常用CMP指令及相应的条件码来操作。

CMP指令的格式为CMP op1 op2用到的标志位有CF,ZF,OF,SF四个,对于两个无符号数的情况,两数相减不可能溢出了,看CF和ZF标志位就可以,如果ZF为1,说明结果是0,那不用说,两数相等了(有符号数也是这样),如果ZF为0,则如果CF为1,表示有借位,op1<op2,否则op1>op2。

对于有符号数,就要看符号标志位SF和溢出标志位OF了,如果是两个同号的数,两数相减也是不可能溢出的,OF一定为0,此时,如果SF为1,则表示op1<op2,否则op1>op2,如果是两个异号的数相减,不溢出的情况跟上面的一样(OF==0,SF==1?op1<op2:op1>op2)。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 16:23:36 | 显示全部楼层
肖-肖 发表于 2021-5-25 16:22
不对吧
我查了下资料
资料如下

我用的JLE不是判断带符号数的大小吗?
省的去判断OF和SF了,挺麻烦的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 16:45:01 | 显示全部楼层
不好意思,上面的回复有点出入,刚翻了下 INTEL 手册,内容如下。

1621932067(1).jpg

1621932117(1).jpg

1621932161(1).jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 19:05:45 | 显示全部楼层    本楼为最佳答案   
79 是最大,79 + 1 = 80
80 是最小
80 < 88

你的数据里面没有 80,最小是 81
没有 79,最大是 78

另一个问题,边界错误
试试这个代码,最后一个数据是 80,最小
DATAS SEGMENT
    ;此处输入数据段代码
    org 0270H
    n db 81H,70H,82H,76H,84H,74H,83H,78H,88H,71H,85H,73H,75H,86H,76H,80H
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    mov si,0270H
    mov al,[si]
    mov bl,al
    mov cl,0FH
    ;mov cl,10H
ks: inc si
    dec cl
    jz over
    cmp al,[si]
    JLE next
    mov al,[si]
next:cmp bl,[si]
    JG ks
    mov bl,[si]
    jmp ks
over:mov si,0280H
    mov [si],bl
    add si,2
    mov [si],al
    MOV AH,4CH
    INT 21H
CODES ENDS
END START
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 19:31:30 | 显示全部楼层
人造人 发表于 2021-5-25 19:05
79 是最大,79 + 1 = 80
80 是最小
80 < 88

第一个问题:
为什么一个字节有符号数中:79为最大正数这个我理解,那为什么80是最小的负数呢?80不应该代表0码?
还是说计算机中没有负数,看成是负数的话也是以补码的方式存放的?
比如81H-->源码--》1000 0001->反码--》1111 1110-》补码-》1111 1111-》FFH
比如89H-->源码->  1000 1001->反码->  1111 0110-> 补码-> 1111 0111-> F7H
那也应该是89H<81H啊?  为什么81H小? 如果直接看成-1也是它大
比如80H-->源码-->1000 0000-->反码-->1111 1111-->补码-->1000 0000 溢出

第二个问题:边界错误是指的什么?
我以为 是比较次数写错了,可是没错啊,就是:0FH 15次啊

   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 20:13:13 | 显示全部楼层
肖-肖 发表于 2021-5-25 19:31
第一个问题:
为什么一个字节有符号数中:79为最大正数这个我理解,那为什么80是最小的负数呢?80不应该代表 ...

负数用补码表示
补码是 原码取反再加 1
举例
求 -1 在内存中的值
原码
00000001
取反
11111110
加 1
11111111
各位全 1,就是 -1
-1 + 1 = 0
11111111 + 00000001 = 1 00000000
最高位丢弃,结果就是 0

-128
原码 128 是
10000000
取反
011111111
加 1
100000000
最高位是 1,其他全 0,是 -128

可以看成最高位是符号位
011111111最大,0x79
100000000最小,0x80,这是有符号数 -128
100000001是0x81,是有符号数 -127

1 < 2
2 < 3
3 < 4
...
0x78 < 0x79
79是最大,再加 1,就变成了最小
0x80(-128) < 0x81(-127)
0x81(-127) < 0x82(-126)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 20:14:32 | 显示全部楼层
肖-肖 发表于 2021-5-25 19:31
第一个问题:
为什么一个字节有符号数中:79为最大正数这个我理解,那为什么80是最小的负数呢?80不应该代表 ...

你运行这个代码,看 282h 的内容,最小应该是 0x80
DATAS SEGMENT
    ;此处输入数据段代码
    org 0270H
    n db 81H,70H,82H,76H,84H,74H,83H,78H,88H,71H,85H,73H,75H,86H,76H,80H
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    ;此处输入代码段代码
    mov si,0270H
    mov al,[si]
    mov bl,al
    mov cl,0FH
    ;mov cl,10H
ks: inc si
    dec cl
    jz over
    cmp al,[si]
    JLE next
    mov al,[si]
next:cmp bl,[si]
    JG ks
    mov bl,[si]
    jmp ks
over:mov si,0280H
    mov [si],bl
    add si,2
    mov [si],al
    MOV AH,4CH
    INT 21H
CODES ENDS
END START
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 20:50:59 | 显示全部楼层
人造人 发表于 2021-5-25 20:14
你运行这个代码,看 282h 的内容,最小应该是 0x80

我复制的代码 只粘贴个头好了
DATAS SEGMENT
    ;此处输入数据段代码
    org 0270H
    n db 81H,70H,82H,76H,84H,74H,83H,78H,88H,79H,85H,73H,75H,86H,76H,80H
DATAS ENDS
运行出来的是:
问2.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-5-25 20:52:10 | 显示全部楼层
肖-肖 发表于 2021-5-25 20:50
我复制的代码 只粘贴个头好了

运行出来的是:

应该是80才对呀,80最小
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 20:54:46 | 显示全部楼层
人造人 发表于 2021-5-25 20:52
应该是80才对呀,80最小

那是为什么?为什么会输出这个?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 20:59:43 | 显示全部楼层
人造人 发表于 2021-5-25 20:52
应该是80才对呀,80最小

哦 我知道了 是你说的那个边界问题 原来如此 因为我是将第一个数给了寄存器所以需要比较16次
应该是10H
我改了之后就对了
问3.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-5-25 21:03:16 | 显示全部楼层
人造人 发表于 2021-5-25 20:14
你运行这个代码,看 282h 的内容,最小应该是 0x80

感谢大佬 感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 10:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表