Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 程序集x86日期到编号-将字符串拆分为较小的部分_String_Assembly_X86_Masm32 - Fatal编程技术网

String 程序集x86日期到编号-将字符串拆分为较小的部分

String 程序集x86日期到编号-将字符串拆分为较小的部分,string,assembly,x86,masm32,String,Assembly,X86,Masm32,事实上,我希望在一个问题上被指向正确的方向 我希望将x86汇编中的日期从格式“DD-MMM-YYYY”转换为唯一的数字,以便稍后对其进行气泡排序并最终转换回 因此,当我有一个字符串输入时,即: .数据 inDate dw“1993年9月8日” 我想把它分成两部分 day = "08" month = "SEP" year = "1993" 这样我可以进一步处理它(我将把SEP转换为“7”,等等) 所以我的问题是,什么是一种简单有效的方式来分解日期(代码方面)?我知道我需要转换日期格式以允许排序

事实上,我希望在一个问题上被指向正确的方向

我希望将x86汇编中的日期从格式“DD-MMM-YYYY”转换为唯一的数字,以便稍后对其进行气泡排序并最终转换回

因此,当我有一个字符串输入时,即: .数据 inDate dw“1993年9月8日”

我想把它分成两部分

day = "08"
month = "SEP"
year = "1993"
这样我可以进一步处理它(我将把SEP转换为“7”,等等)

所以我的问题是,什么是一种简单有效的方式来分解日期(代码方面)?我知道我需要转换日期格式以允许排序,但我是汇编新手,所以我不确定如何分解字符串以便转换它

另外,作为第二个问题,如何将数字从字符串转换为实际的数值

谢谢


注:我想应该注意的是,我使用的是masm32,下一个小程序是用EMU8086(16位)编写的,它从键盘上捕获数字作为字符串,将它们转换为数字进行比较,最后将数字转换为字符串进行显示。请注意,数字是用0AH捕捉的,这需要一个3级变量“str”。您需要的转换过程位于代码的底部(string2numbernumber2string

现在是32位版本。接下来是一个小程序,它为EAX分配一个大数字,将其转换为字符串并将其转换回数值,如下所示:

.model small

.586

.stack 100h

.data

msj1   db 13,10,'Original EAX = $'
msj2   db 13,10,'Flipped  EAX = $'
msj3   db 13,10,'New      EAX = $'

buf    db 11
       db ?
       db 11 dup (?)

.code          
start:
;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax

;CONVERT EAX TO STRING TO DISPLAY IT.
  call dollars  ;NECESSARY TO DISPLAY.
  mov  eax, 1234567890
  call number2string  ;PARAMETER:AX. RETURN:VARIABLE BUF.

;DISPLAY 'ORIGINAL EAX'.
  mov  ah, 9
  mov  dx, offset msj1
  int  21h  

;DISPLAY BUF (EAX CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;FLIP EAX.
  call dollars  ;NECESSARY TO DISPLAY.
  mov  eax, 1234567890
  call flip_eax  ;PARAMETER:AX. RETURN:VARIABLE BUF.

;DISPLAY 'FLIPPED EAX'.
  mov  ah, 9
  mov  dx, offset msj2
  int  21h  

;DISPLAY BUF (EAX FLIPPED CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;CONVERT STRING TO NUMBER (FLIPPED EAX TO EAX).
  mov  si, offset buf  ;STRING TO REVERSE.
  call string2number   ;RETURN IN EBX.
  mov  eax, ebx        ;THIS IS THE NEW EAX FLIPPED.

;CONVERT EAX TO STRING TO DISPLAY IT.
  call dollars  ;NECESSARY TO DISPLAY.
  call number2string  ;PARAMETER:EAX. RETURN:VARIABLE BUF.

;DISPLAY 'NEW EAX'.
  mov  ah, 9
  mov  dx, offset msj3
  int  21h  

;DISPLAY BUF (EAX CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;WAIT UNTIL USER PRESS ANY KEY.
  mov  ah, 7
  int  21h

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h           

;------------------------------------------

flip_eax proc
  mov  si, offset buf  ;DIGITS WILL BE STORED IN BUF.
  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0  ;COUNTER FOR EXTRACTED DIGITS.
extracting:       
;EXTRACT ONE DIGIT.
  mov  edx, 0 ;NECESSARY TO DIVIDE BY EBX.
  div  ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
;INSERT DIGIT IN STRING.
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
;NEXT DIGIT.
  cmp  eax, 0     ;IF NUMBER IS
  jne  extracting ;NOT ZERO, REPEAT.

  ret
flip_eax endp  

;------------------------------------------
;CONVERT STRING TO NUMBER IN EBX.
;SI MUST ENTER POINTING TO THE STRING.

string2number proc

;COUNT DIGITS IN STRING.
  mov  cx, 0
find_dollar:                                          
  inc  cx  ;DIGIT COUNTER.
  inc  si  ;NEXT CHARACTER.
  mov  bl, [ si ]
  cmp  bl, '$'
  jne  find_dollar  ;IF BL != '$' JUMP.
  dec  si  ;BECAUSE IT WAS OVER '$', NOT OVER THE LAST DIGIT.

;CONVERT STRING.
  mov  ebx, 0
  mov  ebp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:         
;CONVERT CHARACTER.                    
  mov  eax, 0 ;NOW EAX==AL.
  mov  al, [ si ] ;CHARACTER TO PROCESS.
  sub  al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
  mul  ebp ;EAX*EBP = EDX:EAX.
  add  ebx, eax ;ADD RESULT TO BX. 
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
  mov  eax, ebp
  mov  ebp, 10
  mul  ebp ;AX*10 = EDX:EAX.
  mov  ebp, eax ;NEW MULTIPLE OF 10.  
;CHECK IF WE HAVE FINISHED.
  dec  si ;NEXT DIGIT TO PROCESS.
  loop repeat ;CX-1, IF NOT ZERO, REPEAT.

  ret 
string2number endp

;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.

dollars proc
  mov  si, offset buf
  mov  cx, 11
six_dollars:      
  mov  bl, '$'
  mov  [ si ], bl
  inc  si
  loop six_dollars

  ret
dollars endp  

;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN EAX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).

number2string proc
  mov  ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  edx, 0 ;NECESSARY TO DIVIDE BY EBX.
  div  ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
  inc  cx  ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  eax, 0  ;IF NUMBER IS
  jne  cycle1  ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  mov  si, offset buf
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
number2string endp  

end start

我了解很多,但我在DD-MMM-YYYY接受我的治疗。因此,我想将DD-MMM-YYYY分解为单独的片段进行转换,以便以这种方式进行排序。要对日期进行排序,需要YYYYMMDD,因为这种格式允许您进行比较。例如,你可以用它来比较出生日期,找出谁更年轻或更老:20150514比20150502晚。对,我明白了。但日期将以DD-MMM-YYYY的形式出现,不幸的是,无法回避这一点。所以,我要做的是将其转换为YYYYMMDD、气泡排序和输出。因此,我的问题是让我在DateToNumber过程中指出正确的方向,该过程将采用DD-MM-YYYY格式parm并返回YYYYMMDD号。如果日期采用DD-MM-YYYY格式,请执行以下操作:从右到左访问所有字符,将每个字符移动到另一个字符串,忽略连字符,您将得到YYYYMMDD号,然后使用我的过程string2number对其进行转换。也许我应该这样做,让我的答案被接受^ uº:你用什么编译器进行汇编?Visual Studio?谢谢,我应该能够调整转换过程以获得所需的内容。这是有道理的。
printf
对于只将字符串传递到
ah=9/int 21h
而不查找
%d
转换或任何内容的函数来说不是一个很好的名称。也许
DOS\u put
会是一个更好的名称(尽管C
put
附加了一个换行符,这需要一个终止的
$
而不是
'\0'')。也许只要
print_string`就更好了。它绝对不是
printf
,因为
f
代表“格式化”。从最有效的数字开始计算并累加
total*=10更有效;总计+=下一位数字
。在asm中,总计可以始终保持在
AX
,并且每个循环迭代只需要一个
mul
.model small

.586

.stack 100h

.data

msj1   db 13,10,'Original EAX = $'
msj2   db 13,10,'Flipped  EAX = $'
msj3   db 13,10,'New      EAX = $'

buf    db 11
       db ?
       db 11 dup (?)

.code          
start:
;INITIALIZE DATA SEGMENT.
  mov  ax, @data
  mov  ds, ax

;CONVERT EAX TO STRING TO DISPLAY IT.
  call dollars  ;NECESSARY TO DISPLAY.
  mov  eax, 1234567890
  call number2string  ;PARAMETER:AX. RETURN:VARIABLE BUF.

;DISPLAY 'ORIGINAL EAX'.
  mov  ah, 9
  mov  dx, offset msj1
  int  21h  

;DISPLAY BUF (EAX CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;FLIP EAX.
  call dollars  ;NECESSARY TO DISPLAY.
  mov  eax, 1234567890
  call flip_eax  ;PARAMETER:AX. RETURN:VARIABLE BUF.

;DISPLAY 'FLIPPED EAX'.
  mov  ah, 9
  mov  dx, offset msj2
  int  21h  

;DISPLAY BUF (EAX FLIPPED CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;CONVERT STRING TO NUMBER (FLIPPED EAX TO EAX).
  mov  si, offset buf  ;STRING TO REVERSE.
  call string2number   ;RETURN IN EBX.
  mov  eax, ebx        ;THIS IS THE NEW EAX FLIPPED.

;CONVERT EAX TO STRING TO DISPLAY IT.
  call dollars  ;NECESSARY TO DISPLAY.
  call number2string  ;PARAMETER:EAX. RETURN:VARIABLE BUF.

;DISPLAY 'NEW EAX'.
  mov  ah, 9
  mov  dx, offset msj3
  int  21h  

;DISPLAY BUF (EAX CONVERTED TO STRING).
  mov  ah, 9
  mov  dx, offset buf
  int  21h  

;WAIT UNTIL USER PRESS ANY KEY.
  mov  ah, 7
  int  21h

;FINISH PROGRAM.
  mov  ax, 4c00h
  int  21h           

;------------------------------------------

flip_eax proc
  mov  si, offset buf  ;DIGITS WILL BE STORED IN BUF.
  mov  bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0  ;COUNTER FOR EXTRACTED DIGITS.
extracting:       
;EXTRACT ONE DIGIT.
  mov  edx, 0 ;NECESSARY TO DIVIDE BY EBX.
  div  ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
;INSERT DIGIT IN STRING.
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
;NEXT DIGIT.
  cmp  eax, 0     ;IF NUMBER IS
  jne  extracting ;NOT ZERO, REPEAT.

  ret
flip_eax endp  

;------------------------------------------
;CONVERT STRING TO NUMBER IN EBX.
;SI MUST ENTER POINTING TO THE STRING.

string2number proc

;COUNT DIGITS IN STRING.
  mov  cx, 0
find_dollar:                                          
  inc  cx  ;DIGIT COUNTER.
  inc  si  ;NEXT CHARACTER.
  mov  bl, [ si ]
  cmp  bl, '$'
  jne  find_dollar  ;IF BL != '$' JUMP.
  dec  si  ;BECAUSE IT WAS OVER '$', NOT OVER THE LAST DIGIT.

;CONVERT STRING.
  mov  ebx, 0
  mov  ebp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:         
;CONVERT CHARACTER.                    
  mov  eax, 0 ;NOW EAX==AL.
  mov  al, [ si ] ;CHARACTER TO PROCESS.
  sub  al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
  mul  ebp ;EAX*EBP = EDX:EAX.
  add  ebx, eax ;ADD RESULT TO BX. 
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
  mov  eax, ebp
  mov  ebp, 10
  mul  ebp ;AX*10 = EDX:EAX.
  mov  ebp, eax ;NEW MULTIPLE OF 10.  
;CHECK IF WE HAVE FINISHED.
  dec  si ;NEXT DIGIT TO PROCESS.
  loop repeat ;CX-1, IF NOT ZERO, REPEAT.

  ret 
string2number endp

;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.

dollars proc
  mov  si, offset buf
  mov  cx, 11
six_dollars:      
  mov  bl, '$'
  mov  [ si ], bl
  inc  si
  loop six_dollars

  ret
dollars endp  

;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN EAX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).

number2string proc
  mov  ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
  mov  cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:       
  mov  edx, 0 ;NECESSARY TO DIVIDE BY EBX.
  div  ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
  push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
  inc  cx  ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
  cmp  eax, 0  ;IF NUMBER IS
  jne  cycle1  ;NOT ZERO, LOOP. 
;NOW RETRIEVE PUSHED DIGITS.
  mov  si, offset buf
cycle2:  
  pop  dx        
  add  dl, 48 ;CONVERT DIGIT TO CHARACTER.
  mov  [ si ], dl
  inc  si
  loop cycle2  

  ret
number2string endp  

end start