免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zylthinking
打印 上一主题 下一主题

[其他] 什么叫非显式的整型立即数 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2012-10-15 13:12 |只看该作者
按照for example的说法,s后面仍然需要是个立即数,但是gcc有可能会把这个立即数放到寄存器里面,因为RISC的指令支持的立即数长度可能不够,你的立即数在指令里放不下。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
22 [报告]
发表于 2012-10-15 13:44 |只看该作者
sonicling 发表于 2012-10-15 13:12
按照for example的说法,s后面仍然需要是个立即数,但是gcc有可能会把这个立即数放到寄存器里面,因为RISC的 ...


我觉得未必这样理解啊, 照这样理解, 那么 编译时未知 该怎么解释, 还有他说s 代替 i 是因为可以产生更佳的代码, 那就是说 i 也行了, 但如果说是s长度不够, i 就够了????
而且, 似乎将-128 - 127 放进寄存器是 K 的功劳, s 应该依旧在强调这是一个编译时未知值。
似乎这个例子也有些难理解, 照他的说法,  K 应该是表示的是排除 -128 - 127 的范围的值的,  Ks 就字面意思, 操作数应该是一个 [min, -128] || [128, max] 范围内的值, 并且是编译时不可知的; 那怎么达到如果是 -128 -- 127 就能放进寄存器的目的的----输入压根就不在这个范围啊

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
23 [报告]
发表于 2012-10-15 14:17 |只看该作者
sonicling 发表于 2012-10-15 13:12
按照for example的说法,s后面仍然需要是个立即数,但是gcc有可能会把这个立即数放到寄存器里面,因为RISC的 ...
  1. int main(int argc, char** argv){
  2.     int result = 10;
  3.     const int n = 0;
  4.     __asm__ (
  5.             "movl %1, %0\n"
  6.             :"=r"(result)
  7.             :"s"(9)
  8.     );

  9.     printf("%d\n", result);
  10.     return 0;
  11. }
复制代码
$> cc -m32 a.c --std=c99
cc1: error in backend: Invalid operand for inline asm constraint 's'!

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
24 [报告]
发表于 2012-10-15 14:43 |只看该作者
回复 23# zylthinking


    你用的 arm? 不熟,但这都不行,我怀疑 ARM不支持立即数到内存

改为:

asm ("mov %1 ,%r0; mov %r0,%0" : "=r"(result) : "s" (????????));

试试

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
25 [报告]
发表于 2012-10-15 14:43 |只看该作者
folklore 发表于 2012-10-15 14:43
回复 23# zylthinking


x86 都不行

论坛徽章:
0
26 [报告]
发表于 2012-10-15 15:51 |只看该作者
回复 23# zylthinking
  1.         case 's':
  2.           if (CONST_INT_P (op)
  3.               || (GET_CODE (op) == CONST_DOUBLE
  4.                   && GET_MODE (op) == VOIDmode))
  5.             break;
  6.           /* Fall through.  */

  7.         case 'i':
  8.           if (CONSTANT_P (op) && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
  9.             result = 1;
  10.           break;
复制代码
这是gcc asm_operand_ok()的部分代码,"s"检查通过的条件是

!CONST_INT_P (op) &&
((GET_CODE (op) != CONST_DOUBLE || GET_MODE (op) != VOIDmode)) &&
CONSTANT_P(op) &&
...

也就是说"s"不能是常量整型或者常量浮点,但必须是常量对象,符合这种条件的对象有
const_vector
const // 常量表达式
label_ref // asm label
symbol_ref // named label

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
27 [报告]
发表于 2012-10-15 15:58 |只看该作者
本帖最后由 zylthinking 于 2012-10-15 15:59 编辑
sonicling 发表于 2012-10-15 15:51
回复 23# zylthinking 这是gcc asm_operand_ok()的部分代码,"s"检查通过的条件是

!CONST_INT_P (op) && ...


const_vector
const // 常量表达式
label_ref // asm label
symbol_ref // named label

这些东西各是什么??? 真的没概念
就常量表达式而言, 我胡试了几个, 似乎都不行

    __asm__ (
        "movl %1, %0\n"
        :"=r"(result)
        :"s"(sizeof(double))
    );

    __asm__ (
        "movl %1, %0\n"
        :"=r"(result)
        :"s"(1 + 1)
    );

LABEL:
    __asm__ (
        "0:"
        "movl %1, %0\n"
        :"=r"(result)
        :"s"(0b)
    );
   
LABEL:
    __asm__ (
        "movl %1, %0\n"
        :"=r"(result)
        :"s"(LABEL)
    );
   

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
28 [报告]
发表于 2012-10-15 16:01 |只看该作者
这也不行:

int test(){
    return 0;
}

int main (int argc, const char * argv[])
{

    int result = 10;
    register int n = 23;
LABEL:
    __asm__ (
        "movl %1, %0\n"
        :"=r"(result)
        :"s"(_test)
    );
   
    printf("%d\n", result);

    return 0;
}

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
29 [报告]
发表于 2012-10-15 16:35 |只看该作者
zylthinking 发表于 2012-10-15 16:01
这也不行:

int test(){

我的理解是s是不能单独用的,你加上r,变成rs试试。

论坛徽章:
0
30 [报告]
发表于 2012-10-15 16:39 |只看该作者
回复 27# zylthinking


   
/* Reference to an assembler label in the code for this function.
   The operand is a CODE_LABEL found in the insn chain.  */
DEF_RTL_EXPR(LABEL_REF, "label_ref", "u", RTX_CONST_OBJ)

/* Reference to a named label:
   Operand 0: label name
   Operand 1: flags (see SYMBOL_FLAG_* in rtl.h)
   Operand 2: tree from which this symbol is derived, or null.
   This is either a DECL node, or some kind of constant.  */
DEF_RTL_EXPR(SYMBOL_REF, "symbol_ref", "s00", RTX_CONST_OBJ)


assembler label指的是asm的label,不是C的控制label。

asm的label不可能用内嵌汇编去定义,只能间接生成,比如 "s"("hello"),字符串hello就让gcc间接生成了一个asm label。

named label指的还是asm的label,但是是命名的。只有全局变量才会有命名的label,比如"s"(&globaln),如果globaln是全局变量,那么gcc会为他生成一个命名label,名字就是globaln,传其地址,其实就是传其label。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP